ASM调用Printf

时间:2013-01-05 06:00:31

标签: linux assembly x86-64 gas att

movl %ebx, %esi
movl $.LC1, %edi
movl $0, %eax
call printf

我使用以下asm代码来打印 EBX 寄存器中的内容。当我使用

movl $1,%eax
int 0x80

echo $?我得到了正确答案,但在第一种情况下出现了分段错误。我正在使用GNU汇编程序和AT& T语法。我该如何解决这个问题?

2 个答案:

答案 0 :(得分: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"

答案 1 :(得分:0)

编辑:正如Jester所说,这个答案仅适用于x86(32位)asm,而提供的样本更有可能用于x86-64。

这是因为printf具有可变数量的参数。 printf调用不会为您恢复堆栈,您需要自己完成。

在您的示例中,您需要编写(32位汇编):

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