Mov и add ничего не делают по какой-то причине - PullRequest
0 голосов
/ 26 января 2019

Я получил этот код от своего университетского профессора, поэтому я вполне уверен, что код работает, но для меня вывод всегда равен 0.

Я пробовал это на Windows и на виртуальной машине с Ubuntu, но все так же.

Я компилирую, используя mingw:

gcc test.c test.s

Это код C:

#include <stdio.h>

int func(int a, int b);

int main()
{   
    int a, b;
    scanf("%d %d", &a, &b);
    printf("%d\n", func(a, b));
    return 0;
}

А это сборка:

.intel_syntax noprefix

.text

    .globl _func

_func:

    enter 0,0

    mov eax, edi
    add eax, esi
    leave
    ret

Для входов 2 и 3 он должен вывести 5, но это всегда 0.

1 Ответ

0 голосов
/ 26 января 2019

Эта часть языка ассемблера ...

    mov eax, edi
    add eax, esi

... является одним из правильных способов добавления первых двух int аргументов в функцию и возврата результата, , если первые два int аргумента функции находятся в регистрах edi и esi.В x86 Linux это верно, если и только если программа скомпилирована с «64-битным ABI», который может или не может быть тем, что ваша виртуальная машина Ubuntu делает по умолчанию.Насколько я знаю, это не так в Windows, независимо от ABI.

Использование 64-битного ABI в Linux, однако, не согласуется с остальным языком ассемблера: в частности, в Linux(все разновидности) функция C с именем func соответствует процедуре на ассемблере с именем func, а не _func.Но это должно было привести к тому, что ваша программа не смогла соединиться (команда gcc выдала бы сообщение об ошибке «неопределенная ссылка на« func »»), чтобы не выдавать неправильный вывод.

СоветуюВернитесь к профессору, который дал вам код сборки, и спросите их, с какой операционной системой и ABI он должен работать, и как адаптировать его к компьютеру (компьютерам), к которому у вас есть удобный доступ.

(ВыВозможно, раньше не встречался термин «ABI». Он обозначает двоичный интерфейс приложения и представляет собой набор правил для того, как работают низкоуровневые детали таких вещей, как вызовы процедур. Например, «x86-64 ELF ABI»,это то, что использует Linux, говорит, что первые два целочисленных аргумента вызова функции помещаются в регистры DI и SI (в этом порядке) перед инструкцией CALL, а целочисленное возвращаемое значение будет найдено в AX после его возврата.x86-64 Windows ABI говорит, что первые два целочисленных аргумента функции помещаются в некоторыедва других регистра - я не помню, какие два - и x86- 32 ELF ABI говорит, что они идут в стек.Все согласны с тем, что в AX появляются целочисленные возвращаемые значения.)

...