【发布时间】:2016-03-30 09:37:54
【问题描述】:
所以,我尝试在 32 位 ATT 程序集中使用 scanf 函数并不断出现分段错误,尽管使用的代码与 Computer Systems: A Programmer's Perspective 中显示的示例几乎相同,并且程序集由我自己的简单 C 输入生成程序。我不知道我做错了什么,希望能得到一些帮助。
我的测试汇编代码(段错误):
.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:
#include <stdio.h>
int 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
【问题讨论】:
-
这是用于什么平台的?
-
@DavidHoelzer
$fmt是符号fmt的值,fmt是地址$fmt的值。你弄错了。 -
除非编译器做错了,否则我确实想要
$fmt。 -
@FUZxxl 如果我没看错你的问题,那是针对 unix 的。
-
@Sunspawn 不同的 Unices 有不同的调用约定和符号命名方案。如果您能将其缩小到一个系统,那将会有所帮助。
标签: c assembly segmentation-fault scanf