Синтаксис GAS, как нажать?

GAS отклоняет все мои pushl'ы с

"неправильный префикс инструкции"

. Я не могу понять, почему... (пример фиктивного кода)

.section .text
        .global _start
_start:
        movl $10, %eax
        pushl %eax
        movl $1, %eax
        int $exit
.data
.equ exit, 0x80

я тоже не смогла

int 0x80

непосредственно в сценарии выше. Он говорит

несоответствие размера операнда для `int'

Я пробовал int 80H, тоже не работает.

Что мне не хватает?


person automaton    schedule 03.07.2014    source источник


Ответы (2)


int 0x80 должно быть int $0x80 (обратите внимание на $, так как это непосредственный операнд)

Что касается pushl, я предполагаю, что вы используете версию ассемблера GNU, настроенную для 64-битных целей. push r32 некодируется в 64-битном режиме, как видно из описания push в Руководство разработчика программного обеспечения Intel. Вместо этого вы можете использовать pushq %rax.

Однако, глядя на ваш код, кажется, что вы пишете 32-битное приложение, поэтому вам, вероятно, следует указать ассемблеру использовать вместо этого 32-битный режим (передать --32 в as, или -m32 в gcc).

Если вы связываетесь с ld, вам также нужно будет указать режим эмуляции для ld с -m, например. -m elf_i386 (чтобы узнать, какие режимы эмуляции доступны, используйте ld -V). Альтернативой может быть ссылка с gcc, например. gcc -m32 foo.o.

person Michael    schedule 03.07.2014

Похоже, вы используете x86_64 архитектуру, но пытаетесь собрать x86 определенный код. Вам нужно передать флаг --32 в gas:

$ as --32 -ofile.o file.asm

С помощью этой командной строки я смог собрать ваш код — без флага я получаю ошибку wrong instruction prefix.

я тоже не смогла

интервал 0x80

Инструкция int требует одного непосредственного операнда (номер вектора прерывания), а gas требует, чтобы непосредственные операнды имели префикс $ (что вы правильно сделали для ваших инструкций mov):

int $0x80
person Andreas Fester    schedule 03.07.2014