2013-01-05 1 views
1
movl %ebx, %esi 
movl $.LC1, %edi 
movl $0, %eax 
call printf 

Я использую следующий код ассемблера для печати, что в EBX регистра. Когда я используюASM вызов Printf

movl $1,%eax 
int 0x80 

и echo $? я получить правильный ответ, но ошибки сегментации в первом случае. Я использую GNU Assembler и AT & T синтаксис. Как я могу исправить эту проблему?

+1

здесь .LC1: .string "% d \ n" –

ответ

0

Редактировать: Как отметил Шторм, этот ответ применим только к x86 (32 бит) asm, тогда как предоставленный образец более вероятен для x86-64.

Это потому, что printf имеет переменное количество аргументов. Вызов printf не восстанавливает стек для вас, вам нужно сделать это самостоятельно.

В вашем примере, вы должны написать (32 бита сборки):

push %ebx 
push $.LC1 
call printf 
add $8, %esp // 8 : 2 argument of 4 bytes 
+0

Да, это правда i n 32-битный режим, и в этом случае он должен поместить аргументы в стек. Но код больше похож на 64 бит, поэтому ваш ответ не применяется. – Jester

+0

@Jester Вы правы. Я предположил, что это 32 бита, потому что я видел только 32-битные регистры и не обращал внимания на сам вызов (без аргумента в стеке). Я сделаю это в своем ответе. – lbonn

1

Судя по коду, вы, вероятно, в 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"