selph
selph
发布于 2022-01-20 / 444 阅读
0
1

《xchg rax,rax》片段分析0x13--等价两数相加2

前言

本次是该系列的的第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

中划线


评论