前言
本次是该系列的的第0x03篇
实验环境:
- Windows10 + VS2022 + masm
0x03
代码片段链接:xorpd | xchg rax,rax 0x03
sub rdx,rax
sbb rcx,rcx
and rcx,rdx
add rax,rcx
代码分析
这里的指令都是很基础的常见指令,就不做介绍了
代码片段分析
给定不同的值给寄存器来观察运行结果,若第一个sub结果为正:
.code
main proc
;rax = 10
;rdx = 15
lea rax, [10]
lea rdx, [15]
sub rdx,rax ;rdx = 5, CF=0
sbb rcx,rcx ;rcx = 0
and rcx,rdx ;rcx = 0
add rax,rcx ;rax = rax = 10
ret
main ENDP
END
若第一个sub结果为负:
.code
main proc
;rax = 10
;rdx = 5
lea rax, [10]
lea rdx, [5]
sub rdx,rax ;rdx = -5, CF=1
sbb rcx,rcx ;rcx = -1
and rcx,rdx ;rcx = rdx = -5
add rax,rcx ;rax = rax + rcx = 5
ret
main ENDP
END
总结如下:短短4行,实现了取二者最小值的功能,这里通过sbb指令判断需要比较的两个寄存器的大小情况,根据sbb指令的结果来判断是否需要让一个操作数变成原来的另一个操作数,能够省略条件判断和跳转,感觉很厉害
.code
main proc
;rax = 10
;rdx = 5
lea rax, [10]
lea rdx, [5]
sub rdx,rax ;通过CF位来标记两个操作数的大小情况
sbb rcx,rcx ;根据CF位来为两种情况准备辅助操作数
and rcx,rdx ;如果rdx大,则rcx为0,rdx小,则rcx为rdx
add rax,rcx ;rax = rax + rcx,如果rdx大,则rax不变,如果rdx小,则rax = rax + 计算后的rdx = rax + rdx - rax = 原来的rdx
ret
main ENDP
END