S B老师根本讲不明白,选的教材也垃圾,很多重要的东西一笔带过,什么玩意儿啊
这里面和伪指令有关的内容下一篇文章再叙述。
我靠。知道吗!我翻遍了整本书关于call指令,它只有不到一页的内容!那么重要的指令CALL和RET,是C语言函数调用的根本,但这两条指令加起来只用了一页就讲完了。
当然这也不奇怪,毕竟所有的寄存器介绍和指令介绍,只有100页。人家王爽老师的《汇编语言》可是写了一本书啊。
功能:改变程序执行顺序(改变IP和CS)。
执行顺序由代码段寄存器和指令指针IP的内容确定,CS和IP结合起来,给出下一条指令在存储器中的位置。
对于转移指令:
- 转移指令的实质:改变IP(或CS)的内容。
- 所有转移指令不会影响标志位。
- 分为无条件转移和条件转移两种。
过程调用和返回指令:
过程(子程序):一段具有特定功能的,供其它程序调用的公用程序。
- 调用子程序时,IP(CS)的内容被压入堆栈栈顶。从子程序返回时,栈顶的内容又被弹出到IP(CS)。
- 子程序执行结束后一般都要返回调用程序。
- 一次定义,多次调用。
- 可带参数调用(提前放到栈或寄存器中)。
段内:只会改变IP
段间:CS和IP都变
直接:地址由#imm给出
间接:地址由reg或mem给出
无条件转移指令
JMP
- 段内直接转移:
JMP #imm(8/16)
指令中直接给出的8/16位的偏移量加到IP
,CS
保持不变。
JMP SHORT #imm8 ; 段内直接短转移
; IP = IP + imm(8)
JMP #imm16 ; 段内直接近转移
JMP NEAR PTR #imm16 ;
; IP = IP + imm(16)
JMP WORD PTR #imm ; 段内间接转移
; IP = imm
- 段内间接转移:
JMP reg(16)/mem(16)
reg/mem中的16位偏移地址送IP。CS保持不变。
转移的目标地址由寄存器或存储单元的内容给出。
JMP reg/mem ; 默认取一个16位数作为IP的值
JMP SI
; IP = SI
JMP WROD PTR[BX+DI]
; IP = [BP:BX+DI]
目标地址以段内偏移的形式给出,而不是相对于IP的位移量,所以它是一个16位的操作数
- 段间直接转移
JMP segment(16):offset(16)
指令中给出的转移地址的16位的段和16位的偏移地址送到CS
和IP
。
JMP #imm1:#imm2
; CS = #imm1
; IP = #imm2
JMP FAR PTR label
; CS:IP = label
- 段间间接转移
JMP mem(32)
指令中给出[mem]
中的16位的段和16位的偏移地址送到CS
和IP
。
OPR只能是存储器操作数
JMP DWROD PTR #imm
; IP = [#imm]
; CS = [#imm+2]
条件转移指令
JXX label
条件转移指令的段内、段间、直接、间接都同上。
条件转移指令根据标志位来决定是否跳转。
指令的转移范围为-128~+127字节。
按所依据条件分三类:
- 根据单个标志为条件进行测试:
- 根据标志间的组合条件进行测试:这里面有符号和无符号数的比大小还不一样
- 根据对CX寄存器值进行测试作为转移的依据:CX为0则跳转
CX为0,则跳转(因为CX总作为计数器使用)
JCXZ label
调用和返回指令
子程序的偏移地址或者段地址直接由CALL指令的操作数给出。
段内、段间、直接、间接都同上。
这里面所有的压栈、弹栈操作都会更改SP寄存器。
- 段内直接调用
格式:CALL imm(16)
CALL执行时,它首先将IP内容压栈,然后把指令中给出的位移量加到IP上。
CALL 0120H
CALL NEAR PTR label
- 段内间接调用
格式:CALL mem(16)/reg(16)
CALL执行时,它首先将IP内容压栈,然后把指令中给出的位移量加到IP上。
CALL BX
; IP = BX
CALL WORD PTR[SI]
; IP = [DS:SI]
- 段间直接调用
CS
内容压栈IP
内容压栈CS
←段地址IP
←偏移地址
CALL #imm1:#imm2
CALL FAR PTR label
- 段间间接调用
子程序的段和偏移地址为存储器的连续4个字节中的内容。前两个字是IP
,节后两个字节是CS
。
CALL #imm
CALL DWORD PTR [DI]
; IP = [DI]
; CS = [DI + 2]
- 返回指令RET
RET会自动的识别到底是段内返回还是段间返回,不用你考虑。它的格式是一样的。
段内返回:弹栈IP
。
段间返回:先弹栈IP
再弹栈CS
。
RET ;
RET n ; 返回后自动丢弃栈顶的n个字节,即更改SP寄存器
SP = SP + n
循环控制指令
- 用在循环程序中以确定是否要继续循环。
- 循环次数通常置于CX寄存器中,CX可以自动减一。
- 转移的目标应在距离本指令-128~+127的范围之内。
- 循环控制指令不影响标志位,但是有些会检测ZF标志位。
LOOP label ; CX不为0时循环
LOOPZ label ; CX不为0且相同时循环
LOOPNZ label ; CX不为0且不同时循环
; 也不一定非得是CMP指令,一些加减指令也会出现改变ZF的情况