Я только начинаю изучать сборку x86, и я немного смущен, почему этот маленький пример не работает. Все, что я хочу сделать, - это распечатать содержимое регистра eax как десятичное значение. Это мой код в AT & T Синтаксис:x86 asm printf вызывает segfault при использовании синтаксиса intel (gcc)
.data
intout:
.string "%d\n"
.text
.globl main
main:
movl $666, %eax
pushl %eax
pushl $intout
call printf
movl $1, %eax
int $0x80
который я скомпилировать и запустить следующим образом:
gcc -m32 -o hello helloworld.S
./hello
Это работает как освобожденный (Печать 666 на консоль). На небольшом примечании я хотел бы отметить, что я не понимаю, что именно «movl $ 1,% eax» и «int $ 0x80» должны быть выполнены здесь. Я также не уверен, что «pushl $ intout» делает. Почему мой вывод состоит из двух отдельных записей стека? И что именно делает макрос .string?
Это только побочные вопросы, так как моя проблема real заключается в том, что я не могу найти способ сделать этот прогон, используя гораздо проще читать/писать/понимать синтаксис Intel.
Вот код:
.intel_syntax noprefix
.data
intout:
.string "%d\n"
.text
.globl main
main:
mov eax, 666
push eax
push intout
call printf
mov eax, 1
int 0x80
Запуск этого же, как и выше, он просто печатает «ошибку сегментации».
Что я делаю неправильно?
На самом деле не рекомендуется использовать 'movl $ 1,% eax; int $ 0x80'. Вы должны просто «вызывать exit», если используете библиотеку C так, как вы. Или вы могли бы просто «ret», предположив, что вы правильно очищаете стек, чего не делаете. У вас есть 2 записи, потому что вы передаете 2 аргумента (строка формата и номер). Что касается того, что делает '.string', я думаю, вы можете догадаться об этом, или, вы знаете, прочитать [manual] (https://sourceware.org/binutils/docs-2.20/as/String.html). – Jester
В чем разница между int 0x80 и вызовом exit? – CaffeineAddict
Первый - это прямой системный вызов, который не оставляет возможности для корректной работы библиотеки C. Кроме того, он менее портативен. – Jester