Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 这是为什么AT&;汇编代码是否给出了分段错误?_Assembly_X86_Scanf_Coredump_Gnu Assembler - Fatal编程技术网

Assembly 这是为什么AT&;汇编代码是否给出了分段错误?

Assembly 这是为什么AT&;汇编代码是否给出了分段错误?,assembly,x86,scanf,coredump,gnu-assembler,Assembly,X86,Scanf,Coredump,Gnu Assembler,这是我的第一个汇编源代码,我想使用scanf函数,但是这个ELF给出了一个分段错误 所以,我尝试使用核心转储解决问题,但我做不到 使用scanf函数 不要只查看核心转储,而是查看如何通过使用si启动gdb中的可执行文件来实现。有关更多GDB提示,请参见的底部 你有一大堆可能导致崩溃的bug,有些肯定会 您定义了一个scanf符号,因此调用scanf跳到那里。 它位于.data部分,因此该页面可能无法执行 或者,给定这些寄存器值,%d“的字节可能会解码为崩溃的x86机器代码 为scanf格式字符

这是我的第一个汇编源代码,我想使用
scanf
函数,但是这个ELF给出了一个分段错误

所以,我尝试使用核心转储解决问题,但我做不到

使用scanf函数
不要只查看核心转储,而是查看如何通过使用
si
启动gdb中的可执行文件来实现。有关更多GDB提示,请参见的底部

你有一大堆可能导致崩溃的bug,有些肯定会


您定义了一个
scanf
符号,因此
调用scanf
跳到那里。

它位于
.data
部分,因此该页面可能无法执行

或者,给定这些寄存器值,
%d“
的字节可能会解码为崩溃的x86机器代码

为scanf格式字符串使用不同的符号名称,如
scanf_fmt
。另外,不要忘记使用
.asciz
将隐式长度C字符串归零


如果您静态链接了它,或者在MinGW或Cygwin上尝试了它,那么libc不会初始化,因为您正在定义
\u start
而不是
main
。在动态链接的Linux可执行文件中,glibc使用动态链接器挂钩来调用其init函数。即使如此,也不建议从
开始使用libc函数


printf
scanf
也可能崩溃,因为当ABI允许堆栈假定为16时,堆栈仅对齐8个字节。在进入
\u start
时,堆栈按16对齐,但在打印F之前,您只需执行1次
推送
+1x
sub$4,%esp

但是大多数Linux发行版不使用
-msse2
构建32位代码,因此编译器不会使用16字节对齐所需的加载/存储来复制内容。(如果使用欠对齐堆栈调用x86-64 glibc的scanf
scanf
会崩溃。)

实际上,使用对齐的堆栈调用
scanf
;从条目到
\u start
的总偏移量为16,因为在
printf
返回后不会浪费清理堆栈的指令。这是一个有效的选择,只要你意识到你在这么做。(它值得一提,和/或您可以使用
mov
而不是
push
,供以后的参数重用这些堆栈插槽。)


我建议查看一个函数的(优化)编译器输出,它可以满足您的需要。e、 g.在

上,不要只看核心转储,而是看你是如何通过在
gdb
内部启动带有
si
的单步指令来实现的。有关更多GDB提示,请参见的底部

你有一大堆可能导致崩溃的bug,有些肯定会


您定义了一个
scanf
符号,因此
调用scanf
跳到那里。

它位于
.data
部分,因此该页面可能无法执行

或者,给定这些寄存器值,
%d“
的字节可能会解码为崩溃的x86机器代码

为scanf格式字符串使用不同的符号名称,如
scanf_fmt
。另外,不要忘记使用
.asciz
将隐式长度C字符串归零


如果您静态链接了它,或者在MinGW或Cygwin上尝试了它,那么libc不会初始化,因为您正在定义
\u start
而不是
main
。在动态链接的Linux可执行文件中,glibc使用动态链接器挂钩来调用其init函数。即使如此,也不建议从
开始使用libc函数


printf
scanf
也可能崩溃,因为当ABI允许堆栈假定为16时,堆栈仅对齐8个字节。在进入
\u start
时,堆栈按16对齐,但在打印F之前,您只需执行1次
推送
+1x
sub$4,%esp

但是大多数Linux发行版不使用
-msse2
构建32位代码,因此编译器不会使用16字节对齐所需的加载/存储来复制内容。(如果使用欠对齐堆栈调用x86-64 glibc的scanf
scanf
会崩溃。)

实际上,使用对齐的堆栈调用
scanf
;从条目到
\u start
的总偏移量为16,因为在
printf
返回后不会浪费清理堆栈的指令。这是一个有效的选择,只要你意识到你在这么做。(它值得一提,和/或您可以使用
mov
而不是
push
,供以后的参数重用这些堆栈插槽。)


我建议查看一个函数的(优化)编译器输出,它可以满足您的需要。e、 g.on

您是如何构建和运行此功能的?如果您静态链接它,或者在MinGW上尝试了此操作,那么libc不会初始化,因为您是从
\u start
运行它的。您是如何构建和运行它的?如果静态链接它,或者在MinGW上尝试了此操作,那么libc不会初始化,因为您是从
\u start
运行它的。
.section .data
 
string: 
.ascii "input yournumber : \0"
 
value: 
.ascii "your value is %d \n\0"

scanf:
.ascii "%d"

.section .text

.globl _start

_start:

movl %esp, %ebp
subl $4, %esp

pushl $string
call printf

leal -4(%ebp), %ebx
pushl %ebx
pushl $scanf
call scanf

pushl -4(%ebp)
pushl $value
call printf

pushl $0
call exit