所以,我试图scanf
在32位ATT程序集中使用该函数并继续得到分段错误,尽管使用的代码Computer Systems: A Programmer's Perspective
与我自己的简单C输入程序生成的汇编代码几乎相同.我不知道我做错了什么,并希望得到一些帮助.
我的测试汇编代码(segfaults):
.data .align 4 fmt: .string "%d" str: .string "Input a number: " .text .global main .type main, @function main: pushl %ebp movl %esp, %ebp subl $40, %esp movl $str, (%esp) call printf leal 36(%esp), %eax movl %eax, 4(%esp) movl $fmt, (%esp) call scanf pushl -4(%ebp) call printf movl %ebp, %esp popl %ebp ret
C代码和它的汇编:
C:
#includeint main() { int i, j; printf("%s\n","Enter 2 numbers:"); scanf("%d %d",&i,&j); printf("i = %d and j = %d\n",i,j); return 0; }
部件:
.file "scan.c" .section .rodata .LC0: .string "Enter 2 numbers:" .LC1: .string "%d %d" .LC2: .string "i = %d and j = %d\n" .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 movl %esp, %ebp .cfi_def_cfa_register 5 andl $-16, %esp subl $32, %esp movl $.LC0, (%esp) call puts leal 28(%esp), %eax movl %eax, 8(%esp) leal 24(%esp), %eax movl %eax, 4(%esp) movl $.LC1, (%esp) call __isoc99_scanf movl 28(%esp), %edx movl 24(%esp), %eax movl %edx, 8(%esp) movl %eax, 4(%esp) movl $.LC2, (%esp) call printf movl $0, %eax leave .cfi_restore 5 .cfi_def_cfa 4, 4 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4" .section .note.GNU-stack,"",@progbits
书中的例子(在剪裁的截图中):
你只是忘记了格式字符串printf
.你有效地做printf(i)
而不是printf("%d", i)
.因此改变:
pushl -4(%ebp) call printf
至:
pushl -4(%ebp) pushl $fmt call printf
PS:学会使用调试器.