2016-11-29 162 views
2

我正在使用x86彙編,我已經開始使用MUL指令了。如何做符號的反義擴展從一個16位寄存器到一個8位寄存器?

以前是這個我的代碼片斷:

mov al, <some_number> 
mul bl 
add al, [edi] 
mov [edi], al 

<some_number>是本大會片段之外定義一個常數,它可以是正數或bl寄存器在代碼的早期設置,它總是正的(因爲它只是在每次合適時溢出/下溢)。我也可以優化最後兩條語句到add [edi], al,但我不是100%確定的,所以我現在不會那樣做。

所以我的程序打了未定義的行爲,在這種情況下是一個無限循環,經過長時間檢查什麼可能是錯誤的,我想我必須使用IMUL,因爲<some_number>可能是負數。

但現在它仍然無法正常工作。然後,我再次查看手冊,並且看到mul bl實際上將結果存儲在ax中。所以我有一個ax簽名的結果,而我想在al無符號(具有上溢/下溢)結果。

所以我的問題是:如何把在ax簽名的結果爲無符號之一al?基本上與符號擴展相反。

注意:我在這裏也包含了我的思維過程,因爲我很可能做的事情並非如預期的那樣,因此目前我找不到答案。

+4

符號擴展(如果它可以被稱爲)的相反是隻是截斷。這已經是你在做什麼了。所以,如果這是不對的,請解釋*應該發生什麼 – harold

+0

@harold我對部分感到困惑。如果我有一個負16位數,那麼MSB將是1,是正確的?如果我繼續只使用較低的8位,那麼我已經基本完全丟失了符號位,不是嗎? – skiwi

+1

這段代碼中沒有分支,那麼你遇到什麼問題?更多上下文將有所幫助正如哈羅德所說,如果ax是一個從8位整數擴展而來的有符號整數,那麼al就已經擁有你想要的。 – Andrew

回答

1

這是我的觀點的一個例子一點:如果相乘的結果是否定的,你NEG它,如果它是積極的,你不NEG它(我在我的編譯器的一個運行此代碼):

mov bl, -5   ;◄■■ NEGATIVE NUMBER. 
    mov al, 10 
    imul bl    ;◄■■ AX = -50 (0xFFCE). 

    cmp ax, 0 
    jl negative  ;◄■■ IF AX < 0 JUMP TO NEGATIVE. 
    jmp continue  ;◄■■ IF AX >= 0 SKIP NEGATIVE. 

negative: 
    neg ax    ;◄■■ AX => POSITIVE (0xFFCE => 0x32). 

continue:  
+3

您可以使用JNL更高效地寫入以跳過NEG,因此其中一個路徑沒有采用分支。 (當然[有無數的方法來獲得一個整數的絕對值](https://godbolt.org/g/eV52mE)) –

3

我無法正確理解問題和評論中的後續行動。讓我知道這是不是一個答案。

我還發現這個答案可能是@ Jose的一個副本,所以我正在考慮將其刪除,特別是如果我發現我誤解了這個問題。


隨着imul bl我們要麼有:

  1. AL * BL的結果融入AL(但結果是符號擴展至AX)。
  2. AL * BL的結果不符合AL

在後一種情況下必須選擇做什麼。
通常必須是按比例的結果返回到8位,這可以是作爲解決比例2 簡單:2 = AXALAL,或者可以是更復雜(包括根本不是一個規模或任何線性操作)。

在前一種情況下,我們需要計算結果的絕對值。
由於情況1假定結果符合AL,所以寄存器AH或者全爲零或者全爲1,匹配AL的符號位。

imul bl   ;Original code 

xor al, ah  ;NOT AL iif the result is negative 
sub al, ah  ;AL = AL - (-1) = AL + 1 iif the result is negative 

這利用了公知的身份,兩兩的補,NEG(X)=未(X)+ 1

+0

IMUL設置OF和CF如果'full_result!= sign_extend(low_half_result)',那麼您可以通過按照IMUL設置的CF或OF分支來檢測情況1與情況2。看到[這個相關的問題](http://stackoverflow.com/a/38254324/224132)關於IMUL的標誌設置的更多討論,相反的問題:使用2操作數IMUL r64,r64,仍然檢測* unsigned * wraparound的64位低半結果。 (tl; dr:只需使用MUL r64,根據需要設置標誌。) –

+1

另外,我同意這個問題是非常有問題的。我沒有看到OP如何確定BL的簽名解釋如果可能溢出,它總是「正面的」。 OP可能真的想要零擴展BL(無符號)和符號擴展AL(帶符號)。爲了清楚地解釋這兩種可能的結果而贊成這種結果,並且如果結果不合適,那麼考慮AL的絕對值可能不是正確答案。 –

+0

@Peter,我認爲這兩種情況是相互排斥的:OP既可以排除情況1,也可以排除情況1。如果他們不能,他們可能錯過了一些東西,問題沒有答案。如果他們可以,那麼採取* AL *的絕對值可以解決他們的問題。 –

相關問題