jmp 指令会立即改变程序的控制流,将指令指针(RIP 寄存器)设置为 jmp 指令的操作数所指定的目标地址。这意味着程序将从这个新地址开始继续执行,而不会执行 jmp 指令后面的任何代码。类似于高级语言的 goto 语句。
这里的 label 是一个标签,表示目标代码的位置。
jmp rax ; 跳转到rax寄存器中的地址
jmp [rbx] ; 跳转到rbx寄存器指向的地址
短跳转使用8位相对偏移量,适用于跳转范围在 -128 到 +127 字节之间的场合。
近跳转使用 32 位相对偏移量,适用于跳转范围更大的场合。
jmp far dword ptr [rip + offset]
远跳转使用绝对地址,通常用于跨段跳转,但在现代操作系统中较少使用。
条件跳转指令对 FLAGS 寄存器中的进位、符号、溢出、零和奇偶校验标志位进行测试,已确认是否存在需要执行的语句分支。
基本操作是:测试一个标志位,以检查该标志位的状态是设置(1)还是清除(0),如果测试成功,跳转到目标标签,否则程序继续执行条件跳转指令的吓一跳指令。
|
|
|
|
有进位(进位标志位 Carry Flag为1),则跳转
|
|
无进位(进位标志位 Carry Flag为0),则跳转
|
|
有溢出(溢出标志位 Overflow Flag为1),则跳转
|
|
无溢出(溢出标志位 Overflow Flag为0),则跳转
|
|
有符号(符号标志位 Sign Flag为1),则跳转
|
|
无符号(符号标志位 Sign Flag为0),则跳转
|
|
为0(零标志位 Zero Flag 为0),则跳转
|
|
不为0(零标志位 Zero Flag 为0),则跳转
|
cmp 比较指令是根据减法的结果设置标志位。与 sub 指令不同的是,cmp 指令不会将减去的结果存储回第一个(目标)操作数,它仅更新标志寄存器以反映操作的结果。
- destination: 目标操作数,通常是寄存器或内存地址
- source: 源操作数,可以是寄存器、内存地址或立即数
cmp 指令仅为整数比较设置标志位,不会比较浮点数值,也不会根据浮点数比较情况设置标志位。
无符号数是只用数值位来表示正数的整数。它不包含任何符号位(即没有正负之分),因此所有的位都用来表示数值大小。比较时,主要关注的是 ZF 和 CF 标志位。
有符号数使用补码表示法来表示正数和负数。最高有效位用作符号位:0 表示正数,1 表示负数。比较时,主要关注的是 SF 和 OF 标志位。
补码表示法是一种计算负数的方式,使得加法和减法操作可以统一处理。以下是将一个有符号整数转换为其补码表示的过程:
-
-
-
-
-
加 1 得到 0111_1011,十进制为 123
-
option casemap:none
.data
s_num1 sqword -3
s_num2 sqword -5
u_num1 qword 3
u_num2 qword 5
.const
signed_msg byte 's_num1 > s_num2', 10, 0
unsigned_msg byte 'u_num1 > u_num2',10, 0
else_msg byte 'Neither condition met',10, 0
.code
externdef printf:proc
externdef ExitProcess:proc
public asmFunc
asmFunc proc
; 有符号数比较
mov rax, s_num1
cmp rax, s_num2
; jg 大于则跳转
jg print_signed_greater ; 如果 s_num1 > num2,跳转到 print_signed_greater
jmp check_unsigned ; 否则检查无符号比较
; 无符号数比较
check_unsigned:
mov rax, u_num1
cmp rax, u_num2
;ja 高于则跳转
ja print_unsigned_greater ; 如果 u_num1 > u_num2,跳转到 print_unsigned_greater
jmp print_else ; 否则跳转到 print_else
print_signed_greater:
lea rcx, signed_msg
call print_message
jmp exit
print_unsigned_greater:
lea rcx, unsigned_msg
call print_message
jmp exit
print_else:
lea rcx, else_msg
call print_message
jmp exit
print_message PROC
subrsp, 56
callprintf
addrsp, 56
ret
print_messageENDP
exit:
xorrcx, rcx ; 设置退出码为 0
call ExitProcess ; 调用 ExitProcess
asmFunc endp
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
辅助标志AF(Auxiliary carry flag)
|
|
|
|
|
|
|
|
|
原文始发于微信公众号(走在网安路上的哥布林):ASM中的控制转移指令
评论