2015-04-07 55 views
0

我很新的裝配,而我試圖建立一個非常簡單的程序在x86即付諸EAX值:(?沒有)測試,如果組裝程序是否正常工作

如果EBX可以通過2^n,其中n爲分割> 3

1如果EBX可以通過被劃分2^3 - > 8

2如果EBX可以通過2^2被劃分 - > 4

3如果EBX可以除以2^1 - > 2

0,如果EBX爲奇數

所以我已經建立了這個方案,並測試了它,一切都正常運行,但我不知道怎麼看,如果它實際上做什麼,我想要它做的。我無法找到任何方式來輸出註冊表的當前價值,而廣泛的互聯網知識只能爲我提供部分答案,而這些答案並沒有讓我走得太遠。

我主要關心的是我不確定ret語句是否返回_main函數,或者只是「中斷」執行。後者是我想要的。那麼我有沒有辦法檢查我的程序是否正常工作?

section .text 
    global _main 

_main: 
    MOV EAX, EBX 
    MOV ECX, 16 
    DIV ECX 
    CMP DX, 0 ;Op=word (1,0,0,0,0), AX := DX:AX/Op, DX -> rest 
    JE end0  ;If number%16 == 0 
    MOV EAX, EBX 
    MOV ECX, 8 
    DIV ECX 
    CMP DX, 0 ;Op=word (1,0,0,0), AX := DX:AX/Op, DX -> rest 
    JE end8  ;If number%8 == 0 
    MOV EAX, EBX 
    MOV ECX, 4 
    DIV ECX 
    CMP DX, 0 ;Op=word (1,0,0), AX := DX:AX/Op, DX -> rest 
    JE end4  ;If number%4 == 0 
    MOV EAX, EBX 
    MOV ECX, 2 
    DIV ECX 
    CMP DX, 0 ;Op=word (1,0), AX := DX:AX/Op, DX -> rest 
    JE end2  ;If number%2 == 0 
    JMP end1  ; 

end8: 
    MOV EAX, 3 
    ret 

end4: 
    MOV EAX, 2 
    ret 

end2: 
    MOV EAX, 1 
    ret 

end1: 
    MOV EAX, 0 
    ret 

end0: 
    ret 
+0

在終端運行程序後,當程序從main返回時返回代碼或退出狀態將是'EAX'的值,如果您隨後鍵入(在windows上)'echo%errorlevel%'或(在linux上)'echo $?'它會在終端顯示那個返回碼。 – James

+0

我很抱歉,這些命令不能在我的調試器上工作。 「在當前情況下沒有符號」回聲「。」它說。我嘗試了美元的語法,但它似乎也沒有用,因爲它說「> $ errorlevel $ 2 = void」 – Iocust

+1

@locust這些命令並不意味着調試器抱歉,我只是給你一種方法來檢查你的程序運行後的返回值,這就是爲什麼我沒有做出這個答案,這些命令是針對終端的,你在同一個終端上運行你的程序後運行'echo'命令,他們會告訴你你的程序返回代碼。 – James

回答

1

您可以使用調試器單步執行您的代碼,並在每個步驟檢查寄存器和內存。

至於你對ret的問題:它是call的對應物,大致來說它會在最近的call之後繼續。 (這是一個簡化的視圖。)請注意,您使用簡單的條件跳轉,如je end0,因此中的ret將不會返回到該位置。相反,它會退出你的_main並繼續在那個叫它的人,這可能是C啓動代碼。它有效地退出你的_main。據我所知,這正是你想要的。

PS:您正在使用DIV錯誤,它只是偶然的工作。它隱含地使用EDX作爲分紅的高32個字,因此您應該始終將其歸零爲32位無符號分割。即使你的評論說,雖然這描述了16位版本的操作。

另請注意,要檢查2的冪可分性,通常使用按位操作,而不是分割。

+0

謝謝你的迅速回答!我確實嘗試使用調試器,但是我將NASM用作IDE,因此,如果在執行過程中沒有遇到錯誤,則隨附的調試器不會提供任何輸出。也許我做錯了什麼。 我不明白你的PS。調零EDX註冊表意味着什麼?我不應該使用AX和DX註冊表並使用其擴展(32位)版本嗎?通過按位運算你是否意味着轉移?我不確定我是否理解他們的概念,所以我採用了安全的方式。 – Iocust

相關問題