extern printf
extern scanf
global main
section .text
main:
sub rsp, 0x10
mov rbx, rsp
add rbx, 0x08
mov rdi, format1
mov rsi, rbx
xor rax, rax
call scanf
mov rdi, format2
mov rsi, [rbx]
xor rax, rax
call printf
add rsp, 0x10
ret
format1:
db "%d", 0
format2:
db "%d", 0xa, 0
value:
dd 0xa
以上来源与
相同#include <stdio.h>
int main(void)
{
int tmp;
scanf("%d", &tmp);
printf("%d\n", tmp);
}
效果很好。但我有疑问。如果我将源代码更改为
extern printf
extern scanf
global main
section .text
main:
mov rdi, format1
mov rsi, value
xor rax, rax
call scanf
mov rdi, format2
mov rsi, [value]
xor rax, rax
call printf
ret
format1:
db "%d", 0
format2:
db "%d", 0xa, 0
value:
dd 0xa
它会导致分段错误。我认为上面的源代码和第一个源代码没有区别。我误解了吗?
答案 0 :(得分:3)
在第一个代码中,您为堆栈上的变量(C代码中的tmp
,在asm代码中未命名)分配空间,并将其地址传递给{{1函数,然后将scanf
写在那里的值传递给scanf
。
在第二步中,您尝试使用在printf
部分中分配的全局value
,但.text在大多数系统上默认为只读。因此,当scanf尝试写入它时,会出现段错误。
在.text
之前粘贴section .data
代替将其放入数据部分,它应该没问题......