【问题标题】:multiplying two 32-Bit Numbers and printing the 64 bit result as decimal NASM assembly将两个 32 位数字相乘并将 64 位结果打印为十进制 NASM 程序集
【发布时间】:2017-12-22 17:52:34
【问题描述】:

我在使用 NASM 程序集时遇到问题。

我不知道如何将两个数字相乘并将它们打印到屏幕上。

问题是我们只允许使用一个只打印 32 位长度数字的函数;不是 64 位长度的数字。

所以我的问题可能出在数学上,我想我需要使用霍纳的方法来获得十进制数;就像我在下面指出的那样。

如果我有

AF / A = 11 remaining 5 
11 / A = 1 remaining 7
1 / A = 0 remaining 1

-> 175 这是正确的结果

但是当我在这里把它分成两个寄存器时,每个 4 字节只是作为一个例子

A | F    A / A = 1 remaining 0 and F / A = 1 remaining 5
         1 / A = 0 remaining 1

->150 错了

这是我的汇编代码

mov eax, [Zahl1]
mul dword [Zahl2]
mov [High], edx


;---- low-----
mov ebx, 10
loopbegin:
;dividing by 10
xor edx, edx
div ebx

;counting
inc dword [counter]

;saving the number 
push edx
cmp eax, 0
jne loopbegin

mov ebx, 10
; --- high ----
mov eax, [High]
highloop:
xor edx, edx
div ebx

inc dword [counter]

push edx
cmp eax, 0
jne highloop

<note> 遵循从堆栈打印数字的循环

【问题讨论】:

  • 这是你所有的汇编代码吗?能否请您编辑以包含所有内容。

标签: assembly x86 nasm


【解决方案1】:

你不能只转换+打印两个半部分,因为高半部分的位代表整个 64 位数字中的4294967296 * hi

4294967296 不是 10 的幂,因此高半部分的位会影响低十进制数字。如果您以 2 的幂为基数(如十六进制或八进制)打印,您的方法将起作用,因为除以基数只是一个移位:即低十六进制数字仅由低 4 位确定。但低位十进制数字取决于所有 64 个二进制位。


相反,您需要进行 64 位除以 10。这需要多个 div 指令,因为如果商溢出 32 位,div r32 (64b / 32b => 32b) 会出错。 有关扩展精度除法的工作代码,请参阅 Assembler 64b division。 (但不要在内存中使用xchg;而是使用一些额外的寄存器)。

(div 很慢,mul 在现代 CPU 上非常快;可能值得进行扩展精度乘法以获得 64b * 64b => 128b 的高半部分,以使 a fixed-point multiplicative inverse 除以快 10 倍。)


此外,您不需要push 数字,也不需要内存中的计数器。只需为从缓冲区末尾开始的指针使用一个额外的寄存器。有关如何编写周边代码,请参阅How do I print an integer in Assembly Level Programming without printf from the c library?,只需使用两条div 指令将内循环中的32 位除法替换为扩展精度即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多