进入用户程序之后,我们首先要做的,就是马上把ds设置为自己的程序段(可以es用来一直指向头部,或者也可以再每一个代码段末尾设置用户程序头部,我们的例子直接用es了),然后就可以进行用户程序所设定的任务了,当然我们的用户程序的的任务比较简单,就是显示一个字符串。
教材上在这一章介绍了call和jmp的全部用法,本来我是想把所有的指令都统一到一起讲的,但是想到call和jmp这两个指令在这里的作用确实太大了,所以直接拿到这里记录就好了。
8086处理器无条件转移指令jmp:
相对短转移jmp short imm8:
操作数是相对于目标位置的偏移量,imm8指示一个8位的有符号数(-127,128),所以这是一个段内转移指令,执行指令后,cs不变,ip会加上偏移地址成为新的偏移地址
(注意,不管是call指令还是jmp指令,因为每执行一次指令,ip的值都会自动到下一条指令的位置上,所以这个偏移量的大小,实际上是ip当前位置的汇编地址(对于其段首)减去目标地址的汇编地址(对于其段首),而不是执行转移前ip的地址
比如:
Goal: jmp near Goal
xor dx,dx
ip的值在执行jmp时,已经是xor的汇编地址的(相对于其段地址),这个时候偏移地址应该是-3(因为jmp near Goal长度是3个字节长度)
)。
16位相对近转移指令jmp near imm16
和相对短转移指令类似,只是操作数可以是16位的了,在没有指示near和short,编译器会根据偏移量长度来确定是near还是short(-127,128是short,大于这个范围是near)。执行指令后,cs不变,ip会加上偏移地址成为新的偏移地址。
16位间接绝对近转移指令jmp near r16\m16
和16位相对近转移指令类似,只是操作数不再是一个16位的立即数了,而是一个16位的通用寄存器或者内存单元,near可以省略,执行指令后,cs不变,ip会被内存\寄存器指示的偏移地址取代。
16位直接绝对远转移指令jmp far imm16:imm16
其中冒号左边的立即数是段地址,冒号右边的立即数是偏移地址,在执行这个指令后,IP会被替换成冒号左边的的值,cs会变成冒号右边的值。far不可以省略。
16位间接绝对远转移指令jmp far m32
可以指定一个32位的内存空间,前16位为偏移地址,后16位位段地址,far不可以省略,在执行这个指令后,IP会被替换成内存指示的低16位,cs会变成内存指示的高16位。
(内存寻址可以是任何一种内存寻址模式(直接寻址,基址寻址,变址寻址,基址变址寻址))。
8086处理器过程调用指令call:
16位相对近调用call imm16
16位相对近转移调用指令是一个3字节的指令,和16位相对近转移指令类似,他的操作数也是一个偏移量,指令执行后,cs不变,ip会加上偏移地址成为新的偏移地址。
16位绝对近调用call r16\m16
和16位间接绝对近转移指令类似,操作数也是一个16位的寄存器或者内存单元,执行指令后,cs不变,ip会被内存\寄存器指示的偏移地址取代。
16位直接绝对远调用call far imm16:imm16
和16位直接绝对远转移指令类似,操作数是两个16位数,冒号左边的立即数是段地址,冒号右边的立即数是偏移地址,在执行这个指令后,IP会被替换成冒号左边的的值,cs会变成冒号右边的值。far不可以省略。
16位相对绝对远调用call far m32
和16位间接绝对远转移指令类似,操作数是一个32位的内存空间,前16位为偏移地址,后16位位段地址,far不可以省略,在执行这个指令后,IP会被替换成内存指示的低16位,cs会变成内存指示的高16位。