x86汇编的强大功能

时间:2012-10-01 20:08:35

标签: assembly x86 masm32 exponent exponentiation

作为ASM编程的入门者我需要在Assembly中获得2的结果,并且我需要你帮助理解为什么我的程序不能产生我需要的结果(它打印4十进制):

.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\msvcrt.inc
includelib \masm32\lib\msvcrt.lib

.data

formatstr db "%d",0

.code 
start:

mov eax , 2
mov ecx , 38
mov esi , eax
mov edx , 0

.while TRUE
    mul esi
    mov esi, edx
    add esi, eax
    mov edx, 0
    mov eax, 2
    dec ecx
    .break .if (!ecx)
.endw




invoke crt__cprintf, addr formatstr, esi


end start

你可以看到我正在使用masm32编写它(如果在那种情况下有任何问题)。

THX。

2 个答案:

答案 0 :(得分:8)

2^38显然不适合一个32位寄存器,例如eax

要存储值2^38274877906944),您需要39位。在32位代码中,您可以使用例如。两个32位寄存器,如edx:eax。但是,在32位代码mul中只接受32位因子(例如寄存器,其他的总是eax),所以使用32位{{1}循环中的中间结果不起作用,因为即使mul存储64位,也无法将中间结果存储在32位寄存器中再次再次 mul中的结果

但您可以使用rcl来计算,例如。 32位代码中的edx:eax

2^38

编辑:受@Jagged O'Neill回答启发的非循环实现。这个没有指数&gt; = 32的跳跃,指数的一次跳跃&lt; 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. 0,ecx大于63 ecxedx:eax

0

答案 1 :(得分:2)

在x86上进行乘法运算时,edx将保留结果的前32位,而eax将保持最低32位。当你这样做时:

mul esi
mov esi, edx
add esi, eax

结果仅在edx为0的情况下才有意义,因此mov / add基本上正在mov esi, eax。如果前32位非零,那么你最终会得到一个相当无意义的上位和下位的混合。