2016-11-17 81 views
0
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 

上面的源代码使用scanf函数一样的是与ASM语言

#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

你踩通过与像GDB调试器? –

+0

结果它说核心被转储,但是我找不到核心文件。如果没有核心文件,我不知道如何使用gdb来分析程序,写入nasm – Damotorie

+0

'gdb。/ nameofprogram',然后使用'layout asm'然后'layout reg'并在main上设置一个断点,使用'b main ',用'run'启动程序,然后用'ni'按指令执行指令?或者像'ddd'一样使用GDB的图形前端? –

回答

3

在第一个代码,你在堆栈上的变量(tmp在你的C代码,无名的汇编代码)分配空间,并通过它的地址为scanf功能,然后传递值scanf在那里写到printf

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

section .data只是value:之前把它在数据部分,而不是它应该是罚款...