nasm 中的jmp(为那激动的一跳)

来源:百度文库 编辑:神马文学网 时间:2024/10/01 10:44:44
第九章: 混合16位与32位代码
------------------------------------
本章将介绍一些跟非常用的地址与跳转指令相关的一些问题, 这些问题当你在
编写操作系统代码时会常遇上,比如保护模式初始化过程,它需要代码操作混合
的段size,比如在16位段中的代码需要去修改在32位段中的数据,或者在不同的
size的段之间的跳转.
9.1 混合Size的跳转.
最常用的混合size指令的形式是在写32位操作系统时用到的:在16位模式中完成
你的设置,比如载入内核,然后你必须通过切入到保护模式中引导它,然后跳转到
32位的内核起始地址处.在一个完全32位的操作系统中,这是你唯一需要用到混合
size指令的地方,因为在它之间的所有事情都可以在纯16位代码中完成,而在它之
后的所在事情都在纯32位代码中.
这种跳转必须指定一个48位的远地址,因为目标段是一个32位段.但是,它必须在
16位段中被汇编,所以,仅仅如下面写代码:
jmp     0x1234:0x56789ABC       ; wrong!
不会正常工作,因为地址的偏移域部分会被截断成‘0x9ABC‘,然后,跳转会是一个
普通的16位远跳转.
Linux内核的设置代码使用‘as86‘通过手工编码来产生这条指令,使用‘DB‘指令,
NASM可以比它更好些,可以自己产生正确的指令,这里是正确的做法:
jmp     dword 0x1234:0x56789ABC         ; right
‘DWORD‘前缀(严格地讲,它应该放在冒后的后面,因为它只是把偏移域声明为
doubleword;但是NASM接受任何一种形式,因为两种写法都是明确的)强制偏移域
在假设你正从一个16段跳转到32位段的前提下,被处理为far.
你可以完成一个相反的操作,从一个32位段中跳转到一个16位段,使用‘word‘
前缀:
jmp     word 0x8765:0x4321      ; 32 to 16 bit
如果‘WORD‘前缀在16位模式下被指定,或者‘DWORD‘前缀在32位模式下被指定,
它们都会被忽略,因为它们每一个都显式强制NASM进入一个已进进入的模式.