2^38
顯然不在一個32位寄存器適合如eax
。
要存儲的值2^38
(274877906944
),你需要39位。在32位代碼中,您可以使用例如。兩個32位寄存器,如edx:eax
。但是,在32位代碼中,mul
只接受32位因子(例如寄存器,其他的總是eax
),因此在循環中使用32位mul
將不起作用,因爲無法存儲您的中間結果在一個32位寄存器的要被相乘再次,即使mul
存儲64位結果在edx:eax
。
但是你可以用rcl
計算如。 2^38
在32位代碼:
xor edx,edx
mov eax,2 ; now you have 2 in edx:eax
mov ecx,38 ; 2^n, in this case 2^38 (any value x, 1 <= x <= 63, is valid).
x1: dec ecx ; decrease ecx by 1
jz ready ; if it's 2^1, we are ready.
shl eax,1 ; shift eax left through carry flag (CF) (overflow makes edx:eax zero)
rcl edx,1 ; rotate edx through carry flag (CF) left
jmp x1
ready: ; edx:eax contains now 2^38.
編輯:通過@Jagged奧尼爾的回答啓發非循環的實現。這一個是不跳躍爲指數> = 32,一個跳躍指數< 32,作品也爲ecx
0,對於ecx
大於63套edx:eax
到0
。
mov ecx,38 ; input (exponent) in ecx. 2^n, in this case 2^38.
; (any value x, 0 <= x <= 63, is valid).
; the code begins here.
xor eax,eax
xor edx,edx ; edx:eax is now prepared.
cmp cl,64 ; if (cl >= 64),
setb al ; then set eax to 0, else set eax to 1.
jae ready ; this is to handle cl >= 64.
; now we have 0 <= cl <= 63
sub ecx,1
setnc al ; if (count == 0) then eax = 0, else eax = 1.
lea eax,[eax+1] ; eax = eax + 1. does not modify any flags.
jna ready ; 2^0 is 1, 2^1 = 2, those are ready now.
mov ebx,ecx ; copy ecx to ebx
cmp cl,32 ; if (cl >= 32)
jb low_5_bits
mov cl,31 ; then shift first 31 bits to the left.
shld edx,eax,cl
shl eax,cl ; now shifted 31 bits to the left.
lea ecx,[ebx-31] ; cl = bl - 31
low_5_bits:
shld edx,eax,cl
shl eax,cl
ready:
什麼是「不起作用?」 – GManNickG
@GManNickG編輯 –
想想存儲2^38需要多少個數字,以及結果寄存器有多少位。 – JohnTortugo