Заставить GCC поместить аргументы в стек перед вызовом функции (используя инструкцию PUSH)

Я начал разработку небольшой 16-битной ОС под GCC / G ++. Я использую кросс-компилятор GCC, который я скомпилировал под Cygwin, я помещаю asm (".code16gcc») в качестве первой строки каждого файла .CPP с использованием синтаксиса Intel ASM и командных строк для компиляции и компоновки файла .CPP выглядят следующим образом:

G++: i586-elf-g++ -c $(CPP_FILE) -o $(OBJECT_OUTPUT) -nostdinc -ffreestanding -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fpermissive -masm=intel

LD: i586-elf-ld -T $(LD_SCRIPT) $(OBJECT_OUTPUT) -o $(BINARY_OUTPUT)

Проблема, с которой я сейчас сталкиваюсь, заключается в том, как GCC переводит код вызова функции в сборку.

Чтобы быть более конкретным, вместо использования инструкции PUSH для передачи аргументов, GCC "вычисляет» смещения относительно ESP, в которых должны располагаться аргументы, и затем использование инструкции MOV для записи стека вручную.

Это не выгодно для меня, так как я полагаюсь на инструкцию PUSH в своем коде сборки. Чтобы проиллюстрировать мою проблему, возьмите эти 2 функции:

void f2(int x);

void f1(){
    int arg = 8;
    asm("mov eax, 5");
    asm("push eax");
    f2(arg);
    asm("pop eax");
}
void f2(int x){
}

В функции f1 я сохраняю EAX с помощью инструкции PUSH, и я ожидаю, что он будет восстановлен до 5 после вызова f2 и выполнения команды "POP EAX " инструкция. Оказывается, однако, что EAX становится 8, а не 5.s, потому что КОДА СБОРКИ GCC генерирует выглядит следующим образом (яМы также включили источник для ясности):

void f1()
C++: {
    push ebp
    mov ebp,esp
    sub esp,byte +0x14

    C++: int arg = 8;
        mov dword [ebp-0x4],0x8

    C++: asm("mov eax, 5");
        mov eax,0x5

    C++: asm("push eax");
        push eax

    C++: f2(arg);
        mov eax,[ebp-0x4]
        mov [dword esp],eax =======>>>>>> HERE'S THE PROBLEM, WHY NOT 'PUSH EAX' ?!!
        call f2

    C++: asm("pop eax");
        pop eax

C++: }
    o32 leave
    o32 ret

void f2(int x)
C++: {
    push ebp
    mov ebp,esp
C++: }
    pop ebp
    o32 ret

Я попытался использовать некоторые флаги компиляции G ++, такие как -mpush-args или -mno-push-args и еще один, который я могу 'не помню, и GCC до сих пор неЯ не хочу использовать PUSH. Версия, которую ям с помощьюi586-elf-g++ (GCC) 4.7.2 (Кросс-компилятор перекомпилирован в Cygwin).

Заранее спасибо!

ОБНОВИТЬ: Вот'Я веб-страницамы нашли:http://fixunix.com/linux/6799-gcc-function-call-pass-arguments-via-push.html

Это просто кажется глупостью для GCC, учитывая, что это ограничивает использование встроенной сборки для сложных вещей. :( Пожалуйста, оставьте ответ, если у вас есть предложение.

Ответы на вопрос(2)

Ваш ответ на вопрос