2016-11-17 73 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:之前把它在數據部分,而不是它應該是罰款...