2012-05-29 39 views
-1

我們必須在大會中編寫代碼,正如你可能知道的那樣。或者教授沒有給我們提供任何有關如何正確編碼或鏈接的信息。我們必須自己學習。明天我必須交出我的工作。 目標是將第n個斐波納契數字打印到控制檯。斐波那契在NASM - seg錯誤

section .data 
    fmt: db "fib=%d",10,0 

section .text 
extern _printf 
global _main, fib 

_main: 
    mov eax, 10  ; e.g. n=10 
    mov ebx, 1  ; we know f_0 and f_1 
    sub eax, ebx ; thats why n-- 
    push eax  ; push n 
    push 0  ; f_0 = 0 
    push 1  ; f_1 = 1 

    call fib 

    push eax  ; in eax the result is stored 
    push fmt 
    call _printf 

    mov ebx, 0 
    mov eax, 1  ; exit(0) 
    int 0x80  


fib: 
    mov ecx, eax 
    pop esi 
    calc: 
    pop ebx 
    pop edx 
    add ebx, edx 
    mov eax, ebx 
    push edx 
    push ebx 
    sub ecx, 1 
    cmp ecx, 0 
    jne calc 
    push esi 
    ret 

在與鏈接器掙扎後,我終於設法組裝和鏈接我的程序。但它不起作用 - 我每次都會遇到分段錯誤。

編輯: 糾正碼 - 我得到的控制檯上的一些文字,但遺憾的是沒有正確的號碼總是顯示「謊= 1」,並再次賽格故障。

回答

0

你有

push 0  ; f_0 = 0 
push 1  ; f_1 = 1 

call fib 

然後

fib: 
    mov ecx, eax 
    calc: 
    pop ebx 
    pop edx 

你不能做到這一點 - 調用指令將推動堆棧上的返回地址,這是你會被彈出的第一件事off in fib。

+0

因此節省通過彈出的數值在第一線,並通過推動恢復在最後一行(前RET)應該工作?任何建議註冊選擇保存? – reijin

+0

感謝您的提示 - 可悲的是我無法提出建議:/ – reijin

+0

是的,如果有點不合常規的話,它會起作用 - 最常見的方法就是像Gunnar建議的那樣設置堆棧框架,並將堆棧中的參數讀入寄存器。臨時寄存器通常是EAX,ECX和EDX--當你返回到最外層的調用範圍時,通常必須保留其餘的。但請注意,這些約定是特定於O/S的。 –

0

我沒有找到大會的辛苦,而是我發現它簡單直接。如果你的老師沒有正確地教導你,你會很樂意在互聯網上搜索信息。幾年前,當我們大多數人開始時,並沒有那麼多的信息,所以我們使用反覆試驗來學習。

我建議你開始簡單並瞭解堆棧。使用這個作爲一個工作示例:

extern printf 
    section .data 
    msg: db "Your sum is %d",10 ,0 

    section .text 
    global _start 

    _start: 
     push 20 
     push 2 
     push 6 
     call AddEm 

     push eax 
     push msg 
     call printf 
     add  esp, 4 * 2 ; printf is C calling convention, we have to adjust stack 

     mov  ebx, 0 
     mov  eax, 1  ; exit(0) 
     int  0x80  

    AddEm: 
     push ebp  ; set up a stack frame 
     mov  ebp, esp ; we could just use esp but we won't 

     mov  eax, [ebp + 8] ; 1st param - 6 
     add  eax, [ebp + 12] ; 2nd param - 2 
     add  eax, [ebp + 16] ; 3rd param - 20 

     mov  esp, ebp ; restore the stack 
     pop  ebp 
     ret  4 * 3  ; passed 3 params, clean up stack 

而這是我如何組裝,鏈接和輸出。

Screenshot

+0

很好的例子,下課後我會看一下。我現在將交付我的缺陷版本,我解決了像「無法解析的參考」,「無法識別的格式」(當使用64位作爲目標文件輸出格式時)解決鏈接器錯誤的時間過多, – reijin