我正在虚拟框中使用Ubuntu 18.04运行程序集GAS代码。
$
这是一个非常简单的方法,应该获取输入整数并打印与该整数相对应的ascii字符。
我使用gcc进行编译:
.section .rodata
input_int: .string "%d"
.text
.global main
.type main, @function
main:
movq %rsp, %rbp #for correct debugging -added by the ide
pushq %rbp
movq %rsp,%rbp
subq $8,%rsp
movq $input_int,%rdi
movq %rsp,%rsi
movq $0,%rax
call scanf
movq %rsp,%rdi
movq $0,%rax
call printf
addq $8,%rsp
movq $0,%rax
movq %rbp,%rsp
popq %rbp
ret
到达gcc -m64 -c ./main.s
gcc -m64 ./main.o -no-pie -fno-pie
./a.out
命令后,它会抛出call scanf
。
尝试以相同的方式运行非常相似的代码:
Segmentation Fault
哪个输出:
.section .data
f: .string "%d"
x: .long 0
.text #the beginnig of the code
.globl main #the label "main" is used to state the initial point of this program
.type main, @function # the label "main" representing the beginning of a function
main:
movq %rsp, %rbp #for correct debugging # the main function:
pushq %rbp #save the old frame pointer
movq %rsp, %rbp #create the new frame pointer
# Get User Input
movq $0, %rax # clear rax
movq $f, %rdi # load format string
movq $x, %rsi # set storage to address of x
call scanf
# Print Input
movq $x, %rdi
movq $0, %rax
call printf
#return from printf:
movq $0, %rax #return value is zero (just like in c - we tell the OS that this program finished seccessfully)
movq %rbp, %rsp #restore the old stack pointer - release all used memory.
popq %rbp #restore old frame pointer (the caller function frame)
ret #return to caller function (OS)
这两个代码之间的主要区别在于,一个使用数据节中的地址,另一个将变量保存到程序堆栈中。
什么可能导致此行为?