前言
本次是该系列的的第0x13篇,本篇介绍了另一种新的两数相加的方法,应该可以算是另一种加法的原理
实验环境:
- Windows10 + VS2022 + masm
0x13
代码片段链接:xorpd | xchg rax,rax 0x13
    mov      rcx,0x40
.loop:
    mov      rdx,rax
    xor      rax,rbx
    and      rbx,rdx
    shl      rbx,0x1
    loop     .loop
代码分析
手工模拟一下过程:
rax 1100b
rbx 0110b
第一轮:
rdx = 1100b	//
rax = 1010b	// 取出rax和rbx里不用计算进位的项
rbx = 0100b	// 取出rax和rbx里需要进行进位的项
rbx = 1000b	// 将进位的项左移一位,变成进位后的值
rax 1010b
rbx 1000b
第二轮:
rdx = 1010b	
rax = 0010b // 将进位后的值和未进行进位的值进行相加,取出不用计算进位的项
rbx = 1000b	// 取出当前需要进位的项
rbx = 10000b// 将进位的项左移一位,变成进位后的值
rax 00010b
rbx 10000b
第三轮:
rdx = 00010b 
rax = 10010b // 再次将进位后的值和未进位的值进行相加,取出不用计算进位的项
rbx = 00000b // 再次取出当前需要进位的项
rbx = 00000b // 再次将进位的项左移一位,变成进位后的值
第四轮:结果未改变	// 直到需要进位的项为0时,结果不再发生变化,循环结束
结果是10010b		// 结果是两数之和
这里每一轮循环都对rax进行和rbx的异或操作,然后rbx左移一位
当rbx为0时,后面的循环不会造成结果发生任何变化
最后的结果是两数相加的和
测试代码:
.code
main proc
    lea rax, [01110b]
    lea rbx, [00110b]
    xor rdi, rdi
    mov      rcx,040h   ;rcx = 0x40 循环0x40(64)次,刚好对应64位
loopA:
    mov      rdx,rax    ;rdx = rax
    xor      rax,rbx    ;rax = rax ^ rbx
    and      rbx,rdx    ;rbx = rbx & rdx
    shl      rbx,01h    ;rbx = rbx * 2,一共会左移64次,每一位都进行了一遍这样的运算
    inc rdi     ;计算循环次数
    cmp rbx,0
    je endA
    loop     loopA      
endA:
	ret
main ENDP
END
中划线
 
          
        