2011-10-24 60 views
2

我是相當新的彙編,我試圖打印出一個給定數字的素因式分解。幾個小時後,我發現了一些關於DIV指令的有用的小技巧,但我無法讓我的代碼做我想做的事。x86彙編DIV素分解

我做了一些非常錯誤的事情,但是我找不到它。有人能爲我找到它嗎?

.data 
myMessage BYTE "Please enter a number to be evaluated:",0dh,0ah,0 
factor DWORD 2 
hold DWORD ? 
.code 
main PROC 
    call Clrscr 

    mov edx,offset myMessage 
    call WriteString   ;Displays myMessage 
    call ReadDec    ;Puts value into EAX register 
    mov edi, factor 
    call prime 


    exit 
main ENDP 

prime PROC 

step1: xor edx, edx 
     div edi 
     cmp edx, 1 
     jz step2 
     add factor, 1 
     mov edi, factor 
     jmp step1 

step2: mov hold, eax 
     mov eax, edi 
     call WriteDec 
     mov eax, hold 
     CMP eax, 1 
     jz step3 
     jmp step1 

step3: 
     exit 
prime ENDP 


END main 

回答

1

如果我明白你在做什麼,我想你對cmpjz是如何工作的誤解。

cmp通過從目的地(第一個)減去源(第二個)操作數而不存儲結果並基於結果設置標誌來工作。對於無符號數字,相關的標誌是進位和零。如果源比目的地大,那麼減法將從其最高位置借用,這是設置進位標誌的結果。如果源和目的地相同,則結果將爲零,並且將設置零標誌。如果源小於目的地,則減法不會導致0或導致進位,因此兩個標誌都將爲0.

jz(和其他條件跳轉)根據當前狀態執行跳轉的旗幟。具體來說,如果設置了零標誌,則jz將執行跳轉。由於cmp設置零標誌以指示其操作數相等,所以如果相等(je)指令跳轉實際上與跳轉爲零指令相同。出於同樣的原因,如果進位(jc)跳轉並且如果跳轉(jb)指令也是相同的。

由於cmp設置標誌以指示哪個操作數較大,所以jz指令可能會造成混淆。如果操作數是等於,它將跳轉,如果其中一個爲零,則跳過。看你的代碼step1

div edi 
cmp edx, 1 
jz step2 

我認爲你正在試圖做的是跳轉到step2如果除法的餘數爲0,但由於方式cmp的作品,你會真正跳到第二步,如果(注意:我將jz更改爲je,因爲它更好地解釋了跳躍的原因。如前所述,它們完全相同)。

div edi 
cmp edx, 0 
je step2 

此外,在沒有找到因子的情況下,您不保留舊值。例如,如果輸入值3,你step1循環會像這樣工作:

  1. 開始:eax = 3,edi = 2
  2. 鴻溝eax通過edi。將商店存儲在eax中,其餘的存儲在edx中。現在
    • eax = 3/2 = 1,並且edx = 3%2 = 1
  3. edx 0?如果是,請打印edi並轉到循環的開頭。
    • 它不是,所以繼續。
  4. 將1加到edi。現在是3.
  5. 用新值執行步驟2,eax = 1和edi = 3。現在
    • eax = 1/3 = 0,edx = 1%3 = 1
  6. ...

注意的是,即使你沒有找到一個因素, eax的值已更改。你需要做的是在分割之前保存它的價值。你可以使用你的hold這個變量,這意味着它只要你找到一個因子就已經更新了。您只需在開始循環前存儲該值,並在每個循環的開始處將其恢復。

 mov hold, eax 
step1: mov eax, hold 
     xor edx, edx 
     ... 
+0

感謝您的幫助。對此,我真的非常感激。 – Shesho