ASM вызов Printf
movl %ebx, %esi
movl $.LC1, %edi
movl $0, %eax
call printf
Я использую следующий ассемблерный код для печати того, что находится в регистре EBX. Когда я использую
movl $1,%eax
int 0x80
и echo $?
Я получаю правильный ответ, но ошибка сегментации в первом случае. Я использую GNU Assembler и AT&T синтаксис. Как я могу исправить эту проблему?
2 ответа
Судя по коду, вы, вероятно, находитесь в 64-битном режиме (пожалуйста, подтвердите), в этом случае указатели имеют 64-битный размер. Вы должны заменить movl $.LC1, %edi
от leaq .LC1, %rdi
(или же leaq .LC1(%rip), %rdi
) и это должно работать.
Кроме того, убедитесь, что:
- вы сохраняете ценность
rbx
в вашей функции - указатель стека выравнивается по мере необходимости
Этот код работает для меня в 64 бит:
.globl main
main:
push %rbx
movl $42, %ebx
movl %ebx, %esi
leaq .LC1, %rdi
movl $0, %eax
call printf
xor %eax, %eax
pop %rbx
ret
.data
.LC1: .string "%d\n"
Редактирование: Как заметил Джестер, этот ответ относится только к x86 (32 бит) asm, тогда как приведенный пример более вероятен для x86-64.
Это потому, что printf имеет переменное количество аргументов. Вызов printf не восстанавливает стек для вас, вам нужно сделать это самостоятельно.
В вашем примере вам нужно написать (32-битная сборка):
push %ebx
push $.LC1
call printf
add $8, %esp // 8 : 2 argument of 4 bytes