使用asm语言的scanf函数

时间:2016-11-17 02:21:01

标签: c assembly scanf

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

它会导致分段错误。我认为上面的源代码和第一个源代码没有区别。我误解了吗?

1 个答案:

答案 0 :(得分:3)

在第一个代码中,您为堆栈上的变量(C代码中的tmp,在asm代码中未命名)分配空间,并将其地址传递给{{1函数,然后将scanf写在那里的值传递给scanf

在第二步中,您尝试使用在printf部分中分配的全局value,但.text在大多数系统上默认为只读。因此,当scanf尝试写入它时,会出现段错误。

.text之前粘贴section .data代替将其放入数据部分,它应该没问题......