1. xchg交换指令
- xchg(Exchange):交换两个操作数的值。这个指令将两个操作数的值互换。
- 例如,xchg ax, bx 将寄存器 ax 和 bx 的值互换。
1.1 xchg reg , reg
以 xchg rax , rbx 为例
- 选中寄存器窗口某个具体寄存器,右键可以直接进行编辑内容。
- 初始rax,rbx寄存器内容如下图:
- 执行 xchg rax , rbx 结果
1.2 xchg mem , reg
xchg mem , rax
Tips:x64gdb奇奇怪怪的,直接用下面的指令覆盖原来的汇编代码,会出现 invalidAddress64Bit 保错导致无法写入汇编代码,猜测写入.bss段地址有问题,但是选择的地址明明有写入权限。
最后使用IDA修改一部分代码之后再次使用x64dbg修改才成功 ,绕了一大圈┭┮﹏┭┮。
- 执行前
- 结果
1.3 间接实现 xchg mem , mem
由于无法直接交换两个内存地址的数据,因此需要使用寄存器作为中转。
mov reg , mem_1 xchg reg , mem_2 mov mem_1 , reg
- 初始数据
- 执行结果
2. inc , dec指令
- inc(Increment):将操作数的值增加1。例如,inc ax 会将寄存器 ax 的值增加1。
- dec(Decrement):将操作数的值减少1。例如,dec bx 会将寄存器 bx 的值减少1。
2.1 inc/dec reg
inc / dec rax
2.2 inc/dec mem
3. neg取反指令
- neg(Negate):将操作数的值取反,即将其变为相反数。例如,neg cx 会将寄存器 cx 的值变为其相反数(如果 cx 的原值是 5,那么 neg cx 后 cx 的值会变成 -5)。
当你执行 neg rax 并且 rax 初始值为 1 时,结果为全 F 的原因是 neg 指令执行了取反操作,具体解释如下:
3.0 neg 指令原理
- 作用:
neg
指令用于将寄存器中的值取反,即计算其相反数。计算过程是通过取反操作和加一来实现的。 - 计算过程
1.初始值:
假设 rax 初始值为 1。在 64 位补码表示中,1 的二进制表示为:
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001
2.取反:
取反操作将所有位反转,即 1 变为 0,0 变为 1。所以,1 的取反值是:
1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110
这是 -2 的补码表示。
3.加一:
将取反后的值加 1
:
1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111
这个值是 -1
的补码表示。对于无符号 64 位整数,-1
表示为全 F
的值,即:
FFFFFFFFFFFFFFFF
结果解释
取反操作:对于 1,取反得到 -2,加 1 得到 -1。在补码表示中,-1 的二进制表示是全 F,即 FFFFFFFFFFFFFFFF。
补码表示:在计算机中,负数通常用补码表示。补码的特性是,-1 的补码表示是所有位都是 1。
因此,当 rax 的初始值为 1 时,执行 neg rax 后,rax 变为 -1,即在 64 位中,全 F 的值 FFFFFFFFFFFFFFFF。
3.1 neg reg
neg rax
3.2 neg mem
4. sub/add指令
- add(Add):将两个操作数的值相加,并将结果存储在目标操作数中。
- 例如,add ax, bx 会将寄存器 bx 的值加到寄存器 ax 中,并将结果存储在 ax 中。
- sub(Subtract):将第二个操作数的值从第一个操作数中减去,并将结果存储在第一个操作数中。
- 例如,sub ax, bx 会将寄存器 bx 的值从寄存器 ax 中减去,并将结果存储在 ax 中。
4.1 sub/add reg , imm
sub / add rax , 0x1
4.2 sub/add mem , imm
4.3 sub/add reg , reg
sub / add rax , rbx
4.4 sub/add 作用 reg 与 mem
sub / add rax , mem 执行结果
sub / add mem , rbx执行结果
5.标志寄存器
- 零标志位(ZF, Zero Flag):
- 作用:当运算结果为零时,ZF 标志被置为 1;如果结果非零,ZF 被清除(设为 0)。
- 用途:ZF 主要用于条件跳转指令中,如 je(Jump if Equal)或 jne(Jump if Not Equal),以根据运算结果是否为零来决定程序的跳转。
- 溢出标志位(OF, Overflow Flag):
- 作用:当算术运算的结果超出了目标寄存器或操作数的表示范围时,OF 标志被置为 1;否则,OF 被清除(设为 0)。对于有符号数的加法或减法,如果结果无法用所用位数表示,则会发生溢出。
- 用途:OF 主要用于有符号数的算术运算中,帮助检测结果是否超出可表示的范围。对于有符号数的运算,OF 是重要的判断依据。
- 符号标志位(SF, Sign Flag):
- 作用:SF 标志反映运算结果的符号。对于有符号数的运算,SF 被设置为结果的最高有效位(即最左边的位)的值。如果结果为负数,SF 被置为 1;如果结果为非负数,SF 被清除(设为 0)。
- 用途:SF 用于有符号数的条件判断中,帮助判断运算结果的符号。
- 例如,条件跳转指令 js(Jump if Sign)可以根据 SF 的值决定是否跳转。