X86程序集中2的幂,计算32位寄存器无法容纳的2^x [英] power of 2 in x86 assembly, calculate 2^x that doesn't fit in a 32-bit register

查看:0
本文介绍了X86程序集中2的幂,计算32位寄存器无法容纳的2^x的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为ASM编程的初学者,我需要在汇编中得到2的38次方的结果,我需要您的帮助来理解为什么我的程序没有产生我需要的结果(它打印4个十进制):

.386
.model flat, stdcall
option casemap:none

include masm32includewindows.inc
include masm32includemsvcrt.inc
includelib masm32libmsvcrt.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编写的(如果在这种情况下有任何问题)。

推荐答案

2^38显然不适合eax这样的32位寄存器。

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

但您可以使用rcl来计算Eg。2^3832位代码:

    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.

编辑:受@Jagge O‘Neill答案启发的非循环实现。对于指数>=32没有跳转,对于指数<;32是一个跳跃,也适用于ecx0,对于大于63个集合edx:eax0

    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:

这篇关于X86程序集中2的幂,计算32位寄存器无法容纳的2^x的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆