Я пытаюсь выделить 40 байт пространства в памяти, вызвав внешнюю команду C malloc в сборке x86 (синтаксис AT&T/Intel). Однако, когда я отлаживаю свою программу, регистр EAX не изменился после вызова команды malloc (насколько я понимаю, процедура использования malloc заключается в том, чтобы поместить количество байтов, которые вы хотите выделить, в регистр EDI, а затем выполнить вызов malloc поставить указатель на блок памяти, размещенный в регистре EAX). Ниже мой код сборки x86:
.extern malloc
.text
.global main
main:
movl %esp, %ebp #for correct debugging
# write your code here
xorl %eax, %eax
movl $40, %edi
call malloc
ret
Я использую 32-битное соглашение (не 64-битное) в Linux.
Команда компиляции:
gcc -m32 -Wall -g -c -o program.o program.s
-march=native
, или в другую библиотеку, скомпилированную с включенным SSE2. (отправьте сообщение @NateEldredge, если вам интересно) 23.11.2020-mpreferred-stack-boundary=4
уже давно используется по умолчанию. Раньше это было просто хорошей идеей, но мало кто заметил, что 32-битный SSE2 генератор кода GCC создавал код, который зависел от него, пока двоичные файлы, построенные таким образом, не получили широкого распространения, и в этот момент меньше всего -Плохой путь вперед состоял в том, чтобы сделать это законом. См. ссылки в верхней части Почему x86-64/AMD64 System V ABI предписывает выравнивание стека по 16 байт? для грязной истории для 32-разрядных: gcc.gnu.org/bugzilla/show_bug.cgi ?id=40838#c91 – увеличенная версия этой сводки. 23.11.2020printf
GLIBC с двойным параметром. 23.11.2020-mpreferred-stack-boundary=4
или по крайней мере 3 до появления SSE, чтобы разрешить 8-байтовое выравнивание дляdouble
локальных переменных на P5 Pentium. В любом случае, тот факт, что ваша 32-разрядная установка де-факто обратно совместима со старыми двоичными файлами, которые могут привести к смещению стека, не означает, что вы можете безопасно говорить всем в Интернете делать то же самое в 32-разрядной версии. битовый код. Эта ошибка/оплошность разработчиков GCC, которая привела к несовместимости ABI, отстой для всех :( 23.11.2020main
, потому что адрес возврата был передан. Чтобы выровнять его обратно по 16-байтовой границе, вам придется уменьшить ESP на 12 к моменту вызоваmalloc
. (или 12, 28, 44 и т. д.) 23.11.202040
байт; они используют EDI только для передачи аргументов. Поэтому вы должны использоватьpush $40
, а неpush %edi
. Кроме того, да, это правильное выравнивание стека, если вы оставляете их сломанныеmov %esp, %ebp
без push/pop EBP вокруг него. Поэтому, если вы собираетесь попытаться исправить всю их функцию, чтобы она была совместима с ABI, затирание EBP является такой же большой или большей проблемой, как выравнивание 16-байтового стека (особенно в 32-битном коде). 23.11.2020main
. Любая другая функция, и это я бы тоже исправил. 23.11.2020main
, и в этом случае ваша программа, скорее всего, сломается, если main уничтожит регистры, которых не должно быть. Или лучший аргумент заключается в том, что будущие читатели могут захотеть использовать этот код в других функциях, поэтому, по крайней мере, комментарии о нарушениях ABI, которые вы разрешаете, имеют смысл. например# push %ebp # skipped in main because its caller usually doesn't care
23.11.2020