ASM call Printf

£可爱£侵袭症+ 提交于 2019-12-24 10:44:25

问题


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

I use the following asm code to print what is in EBX register. When I use

movl $1,%eax
int 0x80

and the echo $? I get the correct answer but segmentation fault in the first case. I am using the GNU Assembler and AT&T syntax. How can I fix this problem?


回答1:


Judging by the code, you are probably in 64 bit mode (please confirm) in which case pointers are 64 bit in size. In a position-depended executable on Linux movl $.LC1, %edi is safe and what compilers use, but to make your code position-independent and able to handle symbol addresses being outside the low 32 bits you can use leaq .LC1(%rip), %rdi.

Furthermore, make sure that:

  • you are preserving value of rbx in your function
  • stack pointer is aligned as required

This code works for me in 64 bit:

.globl main
main:
    push %rbx
    movl $42, %ebx
    movl %ebx, %esi
    leaq .LC1(%rip), %rdi
    movl $0, %eax
    call printf
    xor  %eax, %eax
    pop  %rbx
    ret

.data
    .LC1: .string "%d\n"



回答2:


Edit: As Jester noted, this answer only applies to x86 (32 bits) asm whereas the sample provided is more likely for x86-64.

That's because printf has a variable number of arguments. The printf call doesn't restore the stack for you, you need to do it yourself.

In your example, you'd need to write (32 bits assembly):

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


来源:https://stackoverflow.com/questions/14169140/asm-call-printf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!