Очень возможно в C написать программу, которая компилируется без предупреждений, но вылетает (например, с пустым указателем NULL), и вы увидите точно то же самое. Однако в asm это гораздо более вероятно.
Вы отлаживаете asm с помощью отладчика, например, GDB. См. Советы внизу https://stackoverflow.com/tags/x86/info. И если вы делаете какие-либо системные вызовы, используйте strace
, чтобы увидеть, что на самом деле делает ваша программа.
Чтобы отладить это, вы должны запустить его в GDB. и обратите внимание, что в первой инструкции он вышел из строя, movl $255, %ebx
. Он не обращается к памяти, поэтому выборка кода должна быть ошибочной. Поэтому в ваших разделах должно быть что-то не так, что привело к тому, что ваш код в разделе был связан с неисполняемым сегментом вашего исполняемого файла.
objdump -d
также дал бы вам подсказку: он разбирает .text
раздел по умолчанию, и эта программа не имеет его.
Причина, по которой text
вместо .text
вызывает эту проблему, заключается в том, что значения по умолчанию для разделов со случайными именами, которые не являютсянемногие специально распознаваемые из них - чтение + запись без exec.
В GAS используют .text
или .data
, специальные директивы для быстрого доступа к .section .text
или .data, которые избегают этогопроблема для тех разделов. https://sourceware.org/binutils/docs/as/Text.html
Но не во всех «стандартных» разделах есть специальные директивы, вам все равно нужно .section .rodata
, чтобы переключиться на раздел данных только для чтения, где у вас должно иметьпоставь свой массив. (читай, не пиши. На новых инструментальных цепочках тоже нет exec). Вместо того чтобы перейти к разделу .bss
, вы можете использовать .comm
или .lcomm
(https://sourceware.org/binutils/docs/as/bss.html)
). Другая возможная проблема заключается в том, что вы создаете этот 32-битный код как64-битный исполняемый файл (если только вы не используете 32-битную установку, где as --32
является значением по умолчанию). Использование 32-битных режимов адресации работает в 64-битных режимах, усечение адреса до 32 бит. Это работает, когдадоступ к статическим данным в зависящем от позиции исполняемом файле в Linux, потому что весь код + данные связан с низким 2 ГБ виртуального адресного пространства.
Но любой доступ к (%esp)
или -4(%ebp)
или что-либо другое может привести к ошибкестек в 64-битном процессе отображается на высокий адрес с ненулевыми битами вне 32.
Вы заметили бы эту проблему в GDB, потому что layout reg
будет отображать все 16 64-битных целыхрегистры, RAX..R15.