NASM实现Hello,world
本人以《X86汇编语言:从实模式到保护模式》为参考书。
运行环境
- VirtualBox、.vhd固定大小分配
- 虚拟机的配置为:Other–other/unknow
需要软件:
-
《X86汇编语言:从实模式到保护模式》附带工具包中的"Vhd Writer"工具。
-
NASM编译器
前提了解
①在8086CPU中,其中0xB800~0xBFFF是显卡所在区域,因此,只要将数据写显存,就可以在屏幕上输出。
②一个有效的主引导扇区,最后两个字节应该是0x55和0xaa。
③ROM-BIOS读取主引导扇区(512字节)的时候,会将其加载到逻辑地址0x0000:0x7c00处,也就是物理地址0x07c00处,然后判断它是否有效。
代码实现如下:
;显示Hello,world!
jmp near start ;跳过数据段
mytext: db 'H',0x07,'e',0x07,'l',0x07,'l',0x07,'o',0x07,',',0x07,\
'w',0x07,'o',0x07,'r',0x07,'l',0x07,'d',0x07
start:
mov ax,0x7c0 ;设置数据段基地址
mov ds,ax
mov ax,0xb800 ;设置附加段地址
mov es,ax
cld ;正向传送
mov si,mytext ;设置源索引地址
mov di,0 ;设置目标索引地址:
mov cx,(start-mytext)/2 ;设置传送次数
rep movsw ;开始传送
times 510-($-$$) db 0
db 0x55,0xaa
启动代码:
- 使用nasm将上述代码翻译为.bin文件
- 使用Vhd Writer将bin文件写入到vhd虚拟硬盘中
- 启动虚拟机
如图:
解释:
1. 电脑启动时,会将上述代码顺序加载到0x0000:0x7c00。因此我们要先获得Hello,world的地址。
2. 由于逻辑地址0x0000:0x7c00对应的物理地址是0x07c00,该地址又是段 0x07C0 的起始地址。因此,这个物理地址可以解释为另一个逻辑地址0x07c0:0000。
**3.**movsw每次传送一个字(2个字节),执行时,原始数据串的段地址由DS指定,偏移地址由SI指定,简写为DS:SI。传送目的地由ES:DI指定。传送的字数由CX指定。传送方向由DF指定
**4.**因此,首先将DS设置为0x07c0。然后将ES设置为0xb800
**5.**然后使用cld将DF设置为0,进行正向传送
**6.**字符串的偏移地址就是mytext。
**7.**再使用(start-mytext)/2计算出要传送的字数
**8.**由于movsw每次仅传送一个字,所以要使用rep来重复传送
**9.**最后,使用times重复得到510-( $)个0来填充其余部分,并设置最后两个字节为0x55和0xaa
需要知道的是:
一个字符占用两个字节,一个用来存储ASCII码,另外一个用来存储字符的属性。0x07意味着“黑底白字”