我想把两个12字节的数字相加,并把结果存储在一个16字节的变量中。我该怎么做呢?
section .data
big_num1 dd 0x11111111, 0x22222222, 0x33333333
big_num2 dd 0xffffffff, 0x22222222, 0x33333333
section .bss
result_4word resd 4
我想我可以把数字1的前4个字节和数字2的其他前4个字节相加,以此类推。但是我不知道如何在我的result变量中连接结果。如果需要进位,我应该怎么做?这个解决方案是正确的吗?
xor eax, eax
xor ebx, ebx
mov ecx, 3
loop1:
mov eax, dword[big_num1+4*(ecx-1)]
mov ebx, dword[big_num2+4*(ecx-1)]
mov [result_4word+4*(ecx-1)], eax
adc [result_4word+4*(ecx-1)], ebx
loop loop1
2条答案
按热度按时间czfnxgou1#
此处定义了哪些数字?
因为x86是小端结构,所以数字的最低部分存储在内存中的最低地址。对于 big_num1,第一个定义的双字(值为0x 1111111)位于最低地址,因此是数字的最低部分。在正常的数字表示中,这是位于右手边的部分。
添加大数字
你从右到左添加相应的数字,就像每个人在学校里学的那样。
在这些数字的十六进制表示中,有24位需要考虑。然而,由于体系结构是32位的,我们可以很好地制作3组8位数字。
对于第一组,我们简单地使用
ADD
:对于第二组,我们使用
ADC
从前面的加法中获得一个可能的进位:对于第三组,我们使用
ADC
从前面的加法中获得一个可能的进位:将此转换为循环
这里的关键是,如果我们事先明确清除进位标志**,我们也可以将
ADC
用于第一组**:现在我们可以写一个循环,有3次迭代,但我们必须小心,不要无意中改变进位标志。这就是为什么我使用
LEA
而不是ADD
来推进偏移量。DEC
也是一个不破坏进位标志的指令。我更喜欢组合DEC ECX
JNZ ...
,因为它比LOOP ...
更好:如果在这三次加法之后仍然有一个进位,你必须在 result_4dword 的第四个dword中写一个1,否则你必须在这里写一个0。因为 result_4dword 在.bss部分中,你不应该指望任何预设值,比如零!
请注意,我已经将 result_4word 更改为 result_4dword。这样更有意义...
j1dl9f462#
小学:
开始填写
4+8 = 12,所以2携带1。
在计算机中,您可以:
加a = 4 + 8
模数转换器B = 3 + 7
模数转换器c = 2 + 6
模数转换器d = 1 + 5
然后dcba包含你的结果,它可以根据你的需要缩放。d,c,b,a可以是8位,16位,32位或64位,这取决于指令集。大多数有add和adc,如果它们有标志,没有标志的操作数,则可以通过各种方法对其进行综合,这些方法一点也不困难......(使用32位寄存器将操作数分解为16位数量/内存执行32位加法,现在第16位是进位,将其添加到下一个16位块中,需要一些移位和掩码,但工作原理是相同的,因为您可能有ADC,所以您不需要执行任何操作,只需执行简单的加法、ADC、ADC、ADC......直到完成。
如果在开始之前清除该标志,则可以在循环中使用ADC。
现在,如果你的变量没有与处理器中的加法器对齐,那么你就必须以某种方式合成它。
小学数学对于同样的问题,现在你必须单独做列。
并且你必须手动屏蔽和移位结果(12〉〉1)% 9 = 1(以10为基数)。
然后
这一个携带零: