Язык ассемблера эквивалентен C

Я пытаюсь найти C-эквивалент следующего фрагмента сборки:

        .section .text
        .globl mystery
        .type mystery, @function
    mystery:
        pushl %ebp
        movl %esp, %ebp
        xorl %eax, %eax
        xorl %exc, %ecx
        movl 8(%ebp), %edx

    begin:
        cmpl 12(%ebp), %ecx
        jge  done
        addl (%edx, %ecx, 4), %eax
        incl %ecx
        jump begin

    done:
        movl %ebp, %esp
        popl %ebp
        ret

Я получаю раздел «начало». Это похоже на цикл, который берет параметр из функции и сравнивает его с тем, что находится в %ecx. Если условие jge выполнено, функция возвращает значение, если нет, то добавляет %edx на 4%ecx, перемещает его в %eax, увеличивает %ecx и повторяет цикл снова.

Я действительно не понимаю "загадочной" части. В частности, операторы xorls и movl. Если в %eax или %ecx ничего нет для запуска, что делает xorl. Я предполагаю, что movl берет параметр из функции и перемещает его в% edx?

Любое понимание полезно и ценно.


person MrBaggins    schedule 11.12.2013    source источник
comment
Где вы нашли этот код?   -  person unwind    schedule 11.12.2013
comment
@unwind Я чувствую запах домашней работы.   -  person    schedule 11.12.2013
comment
Исключающее ИЛИ что-то само по себе означает установку его на ноль.   -  person Michael    schedule 11.12.2013
comment
%exc — это %ecx, не так ли?   -  person V-X    schedule 11.12.2013


Ответы (3)


Функция использует передачу аргумента cdecl. C грива, когда вы скомпилируете это, будет _mystery.

int __attribute__((cdecl)) mystery(int * array, int length) {
    // save the rpevious function stack
    // pushl %ebp
    // movl %esp, %ebp

    // xorl %eax, %eax
    int eax = 0;
    // xorl %exc, %ecx
    int ecx = 0;

    // cmpl 12(%ebp), %ecx
    // jge  done
    while (length > ecx) {
        // addl (%edx, %ecx, 4), %eax
        eax += array[ecx];
        // incl %ecx
        ecx++;
        // jump begin
    }

    // restorre previous stack frame
    // movl %ebp, %esp
    // popl %ebp

    // ret
    return eax;
}

Функция вычисляет сумму по массиву целых чисел.

person Sergey L.    schedule 11.12.2013
comment
Или, что более реалистично, сборка исходила из функции C, тело которой было бы: int i, sum; sum = 0; for (i = 0; i < length; i++ ) sum += array[i]; return sum; :) - person lurker; 11.12.2013
comment
@mbrach да, наверное, но я хотел сохранить то же имя, что и регистры, чтобы показать, как они переводятся друг в друга. - person Sergey L.; 11.12.2013

Этот язык ассемблера уже выглядит как дизассемблирование простой программы на C.

mystery:
    % The next two instructions set up the stack frame. %ebp is saved on the 
    % stack to preserve its value. Then %ebp is set to the value in %esp (the 
    % current stack ptr) to establish the stack frame for this function.
    % See http://en.wikibooks.org/wiki/X86_Disassembly/Functions_and_Stack_Frames
    % for details on stack frames.
    pushl %ebp
    movl %esp, %ebp

    % XOR anything with itself zeroes it out since
    % 1 xor 1 is 0, and 0 xor 0 is 0.
    % So the following two instructions clear %eax and %ecx
    xorl %eax, %eax
    xorl %ecx, %ecx     % (note the typo fix :))

    % The following instruction assumes there's a parameter passed from the 
    % caller that's on the stack. It is moving that parameter into %edx
    movl 8(%ebp), %edx
begin:
    ...
person lurker    schedule 11.12.2013

xorl %eax, %eax это стандартный способ сброса регистра (установка его значения на 0). Независимо от того, какое значение имеет регистр, XOR между одними и теми же двумя значениями (битовыми значениями) равен 0.

person bolov    schedule 11.12.2013