32-битный ассемблерный код, работающий на 64-битной платформе - PullRequest
0 голосов
/ 01 февраля 2011

Я изучаю язык ассемблера x86 через книгу Джонатана Барлетта «Программирование с нуля».Недавно я обновил свою систему до 64-битной платформы и появились проблемы с синтаксисом ассемблерного кода, для более конкретной инструкции pushl.Я потратил некоторое время на поиск информации о x86_64 isa, но подумал, что будет лучше закончить изучение основ x86.Для этого мне было интересно, есть ли способ собрать старый синтаксис в 64-битный объект или что-то в этом роде.Или произошли серьезные изменения, которые сделали это невозможным?Я использую Ubuntu 10.10 и переносной ассемблер GNU.

В любом случае.Было бы неплохо, если бы вы указали хорошую книгу или любой другой источник информации о x86_64 или о различиях между ним и его предшественником.

edit: Спасибо!Я получил то, что мне было нужно.Оба ответа были весьма полезны.И не волнуйтесь, я с нетерпением жду, чтобы отпустить X86.

Ответы [ 2 ]

3 голосов
/ 01 февраля 2011

Linux использует указанный xI_86 ABI здесь . Лучшее, что вы можете сделать, это прочитать биты ABI, наиболее подходящие для вашего региона. Вот некоторые из них, которые приходят на ум:

  • В отличие от x86, для x86_64 существует только одно соглашение о вызовах; два, если учесть тот факт, что Microsoft Windows снова совершенно другая.
  • В x86 аргументы функций обычно передаются в стек. в x86_64 первые несколько находятся в регистрах rdi, rsi, rdx, rcx, r8 и r9 для целочисленных типов.
  • Все типы адресов памяти QWORD, поэтому, если вы используете полные регистры (r10 и т. Д.) С синтаксисом AT & T, вам понадобятся movq, addq и т. Д.

Теперь частью дизайна x86_64 было то, что он был обратно совместим с x86, то есть мог выполнять код x86, если операционная система настроена правильно. Таким образом, нет ничего плохого в том, например, сделать это:

nasm -felf32 myprog.asm
gcc -o myprog -m32 myprog.o

Однако имейте в виду; чем больше вы начинаете полагаться на доступность другого кода, тем больше вам нужно 32-битных копий всего. Обратите внимание, что это в основном использует код в 32-битном режиме полностью, в комплекте с соглашением о вызовах и всем прочим. Короче говоря, он должен выполняться и на 32-битной машине. Как говорит Джерри (+1), вы не можете скомпилировать 32-битную сборку, используя 32-битные соглашения в 64-битном режиме. Вы должны соблюдать 64-битный ABI.

Конечно, кроме этого, вы можете свободно использовать в своих подпрограммах такие регистры, как eax, просто имейте в виду, что это влияет на весь rax или, точнее, на половину, которая `eax.

2 голосов
/ 01 февраля 2011

Существует достаточно различий между 32-разрядной и 64-разрядной операциями на уровне языка ассемблера, поэтому вы почти наверняка не захотите просто рассматривать 32-разрядный код, как если бы он был 64-разрядным, и надеяться налучше всего или что-то в этом роде.

Когда вы работаете так же «близко к металлу», как и при написании ассемблера, обычно это происходит по какой-то причине - вы обычно не будете / не будете / не будетеценим ассемблер, пытающийся угадать, что ты на самом деле намеревался, и модифицирующий твой код, чтобы он подходил.В некоторых случаях вы просто потеряете преимущества (например, скорость), а в других это, вероятно, нарушит то, что вы делали целиком (например, когда / если знак расширяет что-то до 64 битов, которые действительно должны были быть расширены до нуля).

...