2016-10-11 163 views
-3

我在學習彙編語言並嘗試解決以下問題。我編寫了代碼,但它不起作用。彙編語言代碼問題

編寫一個程序,該程序使用循環來計算由以下公式描述的斐波那契數列的前七個值:Fib(1)= 1,Fib(2)= 1,Fib(n)= Fib (n-1)+ Fib(n-2)。

我需要用匯編語言編寫的這個程序。使用程序模板中的註釋作爲說明,以彙編語言編寫代碼。我想在彙編語言編寫的程序如下這種編程邏輯:

.data 
;declare an array 
.code 
main proc 
;move 0 into ebx to initialize 
;move 1 into edx to store the first Fib value 
;move edx into an array ; store the first Fib value 

; prepare to loop 
; loop counter for 6 more values 
; move esi,4 
; array index for 3rd Fib value 

L1: 
;move ebx into eax 
;add edx and eax 
;move edx into the array of esi 
; eax = ebx 
; eax = eax + edx 
; store the Fib value 
;move edx into ebx 
; prepare for next iteration 
;move eax into edx 
;add 4 to esi 
;Loop L1 

invoke ExitProcess,0 

我的代碼:

ExitProcess PROTO 

.data 

numbers DWORD 10 DUP (?) 

.code 
main PROC 
    mov ebx,0 
    mov edx,1 
    mov numbers,edx 

    mov ecx,6 
    mov esi,4 

L1: 
    mov eax,ebx 
    add eax,edx 
    mov esi,OFFSET numbers 
    mov [esi],edx 
    mov eax,ebx 
    add eax,edx 
    mov edx,ebx 
    mov eax,edx 
    add esi,4 
Loop L1 

    call ExitProcess 
main ENDP 
END 

我編輯我的代碼如下:

ExitProcess PROTO 

.data 

numbers DWORD 10 DUP (?) 

.code 
main PROC 
    mov ebx,0 
    mov edx,1 
    mov numbers,edx 

    mov ecx,10 
    mov esi,4 
    mov esi,OFFSET numbers 

L1: 
    mov eax,ebx 
    add eax,edx 
    mov [esi],edx 
    mov ebx,edx 
    mov edx,eax 
    add esi,4 
    Loop L1 

    call ExitProcess 
main ENDP 
END 

當我單步執行代碼,eax寄存器和edx寄存器將顯示Fibonacci序列值:1,2,3,5,8,13等。但是,代碼是否將eax寄存器或edx寄存器值存儲在數字a中rray?如果不是,我該怎麼做。

這是一個有效的代碼行嗎?它是否將edx值存儲在numbers數組中?

mov numbers,edx 

如何將eax或edx值存儲在numbers數組中?

+0

堆棧溢出不是一個「請給我teh codez」類網站。 – fuz

+1

下次在填寫代碼時不要刪除註釋。也許你可以壓縮他們一些,但保持它們的參考和調試。 – Ped7g

+0

'mov numbers,edx'在MASM中有效(TASM也在模擬MASM)。它編譯爲'mov DWORD PTR [ds:OFFSET numbers],edx'(詳細描述它的技術方式)。這是有效的,但令人困惑和難堪,因爲它隱藏了源碼閱讀器的'[]'(內存訪問)!你的新編輯幾乎是正確的,只要稍加捕捉,如果你要調試它並觀察內存和esi值,並將它與'OFFSET數字'進行比較,你很快就會修復它,你就近了。 – Ped7g

回答

0

一些代碼中的問題:

mov esi,OFFSET numbers 
mov [esi],edx 

這將初始化esi提前每個寫的,所以你會被改寫元素「numers [0]」所有的時間。

mov eax,ebx 
add eax,edx 
mov edx,ebx 
mov eax,edx 

這並沒有太大的意義......首先你計算eax = ebx+edx ...第二次(EAX已經包含了從以前的行值)。

然後你做eax = edx = ebx;(即你把ebx複製到eax和edx中) 你可能想這樣做,如:mov ebx,edx mov edx,eax

那「招ESI,4」從原來的評論沒有意義,它將使一些意義,因爲add esi,4,你會已經在esinumbers地址(如下面的代碼一樣)。

但它看起來像你不明白什麼地址是,所以在「存儲Fib值」你一次又一次地加載地址。整個過程只需在數組的起始處設置esi一次,然後在每次寫入之後更新指針指向下一個可用空間。


總體得到一些調試和啓動每個指令後看一步的寄存器和存儲器的一步,它與每個指令的描述進行比較,直到它會得到你熟悉的,他們做什麼,它看起來與代碼你不知道這些指令實際上做了什麼。


現在試着去了解這一點:

mov esi,OFFSET numbers ; esi = target array address 
    mov ecx,7 ; produce seven numbers 
    xor ebx,ebx ; ebx = 0 F(-1) 
    mov edx,1 ; edx = 1 F(0) 
    jmp store_number 
loop1: 
    add ebx,edx ; ebx: F(n) = edx: F(n-1) + ebx: F(n-2) 
    xchg ebx,edx ; ebx: F(n-1), edx: F(n) 
store_number: 
    mov [esi],edx ; array_pointer[0] = F(n) 
    add esi,4  ; ++array_pointer 
    loop loop1 

同樣要注意許多指令都在做純紙式工作(「F(N)= F(N-1)+ F(N -2)「)和」7號碼「,以及有多少指示只是爲了支持這件事。你可能會不同意,但我會說cca。 50%是「支持cruft」,大部分是直接紙 - >代碼重寫。

學習大會時記住這一點,確保你有你想要達到的公式層次什麼第一思路很清晰,然後嘗試做 ...只會增加支持代碼在絕對必要的。不要僅僅寫一些隨機的指令,因爲它看起來像個好主意,或者你之前寫過這樣的指令。指令要麼「做某件你想要的事」,要麼將其切除。在評論


編輯:

mov esi,OFFSET numbers店符號 「號」 的地址爲esi。如果您將numbers聲明爲​​或DWORD,則地址指向分配的內存的第一個位置(第一個字節),這並不重要。

字節/雙字/ dup對於分配足夠的總空間很重要,但不會影響地址本身(「符號」)。

mov [aaa],vvv將值「vvv」存儲到地址「aaa」的存儲器中(請查看指令說明以查看可能的組合)。

因此mov [esi],edx之後mov esi,OFFSET numbers之後將存儲每個值在「數字[0]」。在調試器中,那個esi每次被那個mov esi,OFFSET numbers復位。

請不要使用夸克語法mov numbers,edx,其存儲值裝入只在MASM「數字」陣列(和TASM當模擬MASM怪異模式),在適當的英特爾語法指針/地址的[]信號解除引用的使用,因此在讀取源代碼時很容易判斷指令是僅以寄存器/立即數運行還是訪問存儲器。 (lea reg,[address]是例外,即不訪問內存,只計算地址)。在NASM中,mov numbers,edx根本無法編譯,而mov edx,numbers不會加載數組中的第一個值,而是地址本身(在MASM/TASM中,您必須在符號之前寫入OFFSET)。

所以

「做的代碼存儲的數字數組中的EAX寄存器的值?」

不,它只覆蓋第一個numbers[0]值。

+0

我編輯我的代碼如下:(?) – ISM34

+0

ExitProcess的原型 。數據 號碼DWORD 10 DUP .CODE 主PROC \t MOV EBX,0 \t MOV EDX,1個 \t MOV號碼,EDX \t MOV ECX,10 \t MOV ESI,4 L1: \t MOV EAX,EBX \t添加EAX,EDX \t MOV ESI,偏置號 \t MOV [ESI],EDX \t MOV EBX,EDX \t MOV EDX,EAX \t添加ESI,4 \t環路L1 \t呼叫了ExitProcess 主ENDP END – ISM34

+0

當我單步執行代碼,eax寄存器將顯示Fibonacci序列值:1,2,3,5,8,13等。但是,代碼是否將eax寄存器值存儲在numbers數組中?如果不是,我該怎麼做。 – ISM34