2012-12-11 74 views
3

我有一些使用scanf和printf的彙編代碼,我遇到了一些問題。當這兩個函數在相同的代碼中使用時,寄存器中的值似乎會丟失。該程序基本上加載一個數字並打印出來。我們運行它使用程序集中的C調用約定(64位) - scanf

nasm -f elf64 file.asm && gcc -o file file.o && ./file 

在Linux上

這裏是我們的代碼:

extern printf 
extern scanf 
section .data 

    a db "set: ", 0 
    b db "not set: ", 0 
    reading db "Please enter a number: ", 0 
    message db "\n", 0 
    printsent db "%s", 10, 0 
    printint db "%d", 10, 0 
    printchar db "%c", 10, 0 

    readInt db "%d", 0 
    input db "%d", 0 

section .text 
    global main 

main: 

hatta: 
push rbp, 
mov rbp, rsp, 
push rbx, 
xor rax, rax, 
mov rdi, printsent, 
mov rsi, reading 
call printf, 
pop rbx, 

xor rax, rax, 
mov rdi, readInt, 
call scanf, 
mov rbx, rdi 

push rbx, 
xor rax, rax, 
mov rdi, printint, 

mov rsi, rbx, 
call printf, 
pop rbx, 

pop rbp, 
ret 

奇怪的是,如果線mov rdi, printint,被刪除,我們得到正確的值。但是,如果我們對printsentence執行相同的操作,則會出現分段錯誤。有誰能告訴我們這個原因嗎?

謝謝!

+1

你將不得不說什麼操作系統,因爲調用約定各不相同。調用約定在正則函數和可變參數函數(如printf)之間也有所不同,所以請仔細閱讀您讀取的信息。 – ams

+2

我想這是一個練習,因爲我不認爲在彙編中編寫這樣的東西現在還是有意義的。最簡單的方法是編寫對應的C程序,帶上你最喜歡的編譯器,並用'-S'或相當於彙編器編譯它。 –

回答

1

我不明白你爲什麼在這裏有C標誌,不涉及C代碼,但你的問題:

至於我記得在Linux的glibc的64位調用約定printf(format, argument)format in rdiargument in rsi

如果你刪除mov rdi, printsent,那麼你打電話printf(undefined,"Please enter a number: ")。您沒有在rdi中提供格式參數,但printf 不知道那個並且在那一刻使用rdi中的任何內容。很可能是無效的內存地址,因此調用SIGSEGV

默認情況下,x86中的函數調用應該對參數沒有破壞性,儘管這不是必需的。標準庫函數通常是。他們通過將參數推入堆棧並在完成時重新加載它們來實現此目的。

因此,當你調用scanf(readInt, ...)將指針恢復到readInt具有相同內容printintrdi當它返回。因爲rdi包含一個指向您所需格式的有效指針,所以刪除行mov rdi, printint,不起作用。

+0

「默認情況下,x86中的函數調用應該對參數無破壞性」 - 對於Win64或UN * X x86_64上的64位x86,情況並非如此。用於參數傳遞的寄存器是scratch,即使它實際上沒有任何參數,也可以被調用的函數進行任意修改。 –

1

,我們在您scanf使用,可能是基於一個錯誤的假設兩個錯誤:你似乎意味着scanfrdi,同時還需要與格式"%d"沒有進一步的說法返回裝載數量。事實上,數字(如果掃描成功)返回到第二個參數指向的內存中。因此,以下更改會使代碼正常工作。

pop rbx,        | ;delete 
             = 
xor rax, rax,       = xor rax, rax, 
mov rdi, readInt,      = mov rdi, readInt, 
             > mov rsi, rsp 
call scanf,       = call scanf, 
mov rbx, rdi       | pop rbx, 

關於如果線路MOV RDI,printint,被刪除,我們得到正確的價值觀 - 我對此表示懷疑。