【问题标题】:How to put value that has size of qword and bigger, in a dword array?如何将具有 qword 和更大大小的值放入 dword 数组中?
【发布时间】:2016-01-01 09:40:36
【问题描述】:

我正在尝试做一个需要 2 个数字的程序,例如:
num1 = 123
num2 = 24
程序正在对 num1 中的数字求和,在本例中,和为 6,程序需要打印我需要添加多少次 90,数字之和将等于 num2。 在本例中,我们需要将 90 添加两次,因为:1239090--> 1+2+3+9+0+9+0 = 24

现在,我加 90 的方法是取 num1,将其乘以 100 并加 90:
123*100 = 12300 --------> 12300+90 = 12390(第一次)

我的问题是输入如下:
num1 = 123
num2 = 42

现在,num1 假设最后为 123 90 90 90 90 大于 dword 大小!

现在我认为我需要一个 dword 数组,所以如果结果大于 dword 大小,它将把剩余的结果放在数组的下一个 dword 单元中。 但是我不知道该怎么做,我试图通过将EBX指向数组的offset然后放入[EBX]的值来放置结果,但发生的事情是它只是压缩数组的第一个 dword 单元中的值。

那么如何将大于 DWORD 大小的值放入 dword 数组中?
我的代码是:

.386 
.MODEL Flat, STDCALL 
option casemap:none 

SomeFunc proto :DWORD
MulBy100 proto :DWORD

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

.data
    var dd 30 dup (0)     ;The array to put the result 
    count dd 0            ;count how many 90 to add
    SumHash dd 0          
    SumDigits dd 0
    fmt2 db '%d',0

.code

ReturnHashCode proc Number:DWORD
    mov SumHash,0
    Lop:
        mov eax,Number
        mov ebx,10
        xor edx,edx
        div ebx
        add SumHash,edx       ;num%10 add to SumHash (123-->3)
        mov Number,eax        ;num/10 go to Number   (123-->12)
        cmp Number,0          ;check if there is no more digits to add
        ja Lop

    ret
ReturnHashCode endp


MulBy100 proc thevar:DWORD
    mov ecx,99        ;adding 100 times the number to itself = number*100
    mov ebx,thevar    ;point to the var dword array
    mov eax,[ebx]     ;eax hold the num1 that we input (123 for example)
    MulLoop:
        add [ebx],eax ;adding the number to itself 100 times
        loop MulLoop
    ret
MulBy100 endp


start:
    INVOKE crt_scanf,offset fmt2,offset var        ;in this example = 123
    invoke crt_scanf,offset fmt2,offset SumDigits  ;in this example = 24
    countNop:
        invoke ReturnHashCode,var      ;return sum of digits to SumHash variable
        mov eax,SumDigits              ;in this example = 24          
        cmp eax,SumHash                
        je End_countNop
        push offset var                ;send the pointer to the var array dword size that suppost to hold the value (1239090....90)
        call MulBy100                  ;multiply by 100
        add var,90                     ;add 90
        inc count                      ;add to count 1 because we add 90
        jmp countNop
    End_countNop:
        invoke crt_printf,offset fmt2, count            ;printing how many times we added 90     
end start

感谢帮助者!

【问题讨论】:

  • 附加 9 对数字和的影响与附加 90 相同,而且您已经知道效果:它增加了 9(因此您可以将差除以 9)。一定要明确计算数量吗?
  • @harold我没提,但我必须用90,而不是9。这个程序是一个大程序的一部分,我必须在其中使用90。你能解释一下你写的第二句话吗(“你已经知道效果:它加了 9(所以你可以将差除以 9)。”?我没明白你的意思。“你必须明确计算数字?” - 我也不懂这个问题..你能解释一下你的意思吗?谢谢你的帮助。
  • 附加 9(或 90)会保留原始数字不变,但你有一个额外的 9。所以数字总和正好增加 9。另外,你可以使用mul,你可以存储两个相邻双字中的东西。
  • @harold 但存储在 2 dword 中仍然对我没有帮助,因为如果数字使结果大于 2dword 怎么办?但你让我弄清楚,我可以取 123,24 并做:1+2+3 = 6 ---> 24-6 = 18 ---> 18\9 = 2。这是时间加 90。但无论如何,我想知道是否有办法获取比 dword 更大的数字(如 qword 大小)并将其存储在 dword 数组中,而不用 dword 大小压缩数字。

标签: arrays assembly masm 32-bit dword


【解决方案1】:

当数字变得太大时,您需要级联指令。在这里您可以使用adc 指令。我将显示 64 位结果:

MulBy100 proc thevar:DWORD
  mov  ecx, 99        ;adding 99 times the number to itself = number*100
  mov  ebx, thevar    ;point to the var dword array
  mov  eax, [ebx]     ;edx:eax hold the num1 that we input (123 for example)
  mov  edx, [ebx+4]
 MulLoop:
  add  [ebx], eax     ;adding the number to itself 99 times
  adc  [ebx+4], edx
  loop MulLoop
 ret
MulBy100 endp

请注意编写正确的 cmets。您只需添加 99 次即可乘以 100。

通过使用额外的寄存器,您可以轻松地转换此代码以支持 128 位结果。

【讨论】:

  • 确实意识到x86有一个双寄存器大小的乘法指令?
  • @EOF 我肯定会这样做,但是使用 30 个 dwords 的数组对我们没有太大帮助!
  • 我敢肯定,在这种情况下,即使是教科书的多位数乘法也会变得更容易和更快。
猜你喜欢
  • 1970-01-01
  • 2020-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多