|
【汇编语言程序】在软盘启动画面上用循环显示”0123456789“ |
一派护法 十九级 |
先看最终运行效果:
|
一派护法 十九级 |
复制光盘里的G:\tolset文件夹到硬盘上,比如D:\tolset。然后复制G:\projects\02_day\helloos4文件夹到刚才的tolset文件夹里面。进入helloos4文件夹,用记事本打开ipl.nas文件,把里面的内容全删了,改成下面的程序:(这个程序是我自己写的)
ORG 0x7c00 JMP entry DB 0x90
DB "HELLOIPL" DW 512 DB 1
DW 1 DB 2 DW 224 DW 2880 DB 0xf0 DW 9 DW 18 DW 2 DD 0 DD 2880 DB 0, 0, 0x29 DD 0xffffffff DB "HELLO-OS " DB "FAT12 "
RESB 18
; 这是程序开始执行的地方 entry: MOV AX, 0 MOV SS, AX MOV SP, 0x7c00 MOV DS, AX MOV ES, AX MOV DL, 0 ; 把寄存器DL的值设为0
putloop: ; 关于用BIOS显示字符,请参考书上第38页 ; 寄存器AL指定要显示什么字符 MOV AL, '0' ADD AL, DL ; 要显示的字符为'0'+DL。比如'0'+4就是'4'
; 以下三行是为了显示AL中保存的字符 MOV AH, 0x0e ; AH必须为0x0e MOV BX, 15 ; BH = 0, BL = 15,合起来就是BX=15,这个15是指颜色的编号为15 INT 0x10 ; 执行BIOS中的一个函数,该函数的地址是0x10,该函数的作用是显示一个字符 CMP DL, 9 ; 判断DL的值是否等于9 JE fin ; 如果等于9,就跳到fin标签上执行 ADD DL, 1 ; 如果不等于9,那么就把DL的值加1 JMP putloop ; 然后跳到putloop上执行,显示下一个字符
; 无限循环 fin: HLT ; CPU休眠,当鼠标或键盘有动作时才被唤醒 JMP fin ; 跳回fin标签
RESB 0x7dfe-$ ; 把启动区剩下的字节全部写上0 DB 0x55, 0xaa ; 启动区标志,表示软盘上有启动程序
|
一派护法 十九级 |
最后,依次双击文件夹里的asm.bat,makeimg.bat和run.bat文件,即可运行程序。
其中asm.bat把汇编语言程序编译为512字节的ipl.bin文件,这是软盘的头512字节的启动区。然后用makeimg.bat把该启动区变成软盘iso映像文件,最后run.bat启动虚拟机运行这个软盘上的启动程序。
|
一派护法 十九级 |
【程序2】 ORG 0x7c00 JMP entry DB 0x90 DB "HELLOIPL" DW 512 DB 1 DW 1 DB 2 DW 224 DW 2880 DB 0xf0 DW 9 DW 18 DW 2 DD 0 DD 2880 DB 0, 0, 0x29 DD 0xffffffff DB "HELLO-OS " DB "FAT12 " RESB 18 ; 这是程序开始执行的地方 entry: MOV AX, 0 MOV SS, AX MOV SP, 0x7c00 MOV DS, AX MOV ES, AX MOV DL, 0 ; DL的初值为0 ; 准备好显示字符的所需参数: AH和BX MOV AH, 0x0e MOV BX, 15 putloop: ; 显示字符DL + '0' MOV AL, DL ADD AL, '0' INT 0x10 ; 显示逗号 MOV AL, ',' INT 0x10 ; 显示空格 MOV AL, ' ' INT 0x10 ; 如果DL==9就跳转到fin,否则DL++并跳转到putloop CMP DL, 9 JE fin ADD DL, 1 JMP putloop ; 无限循环 fin: HLT JMP fin RESB 0x7dfe-$ DB 0x55, 0xaa 【运行结果】
|
一派护法 十九级 |
由于DL是CPU上的一个寄存器,不是内存上的一个存储单元,所以这个程序执行起来肯定比C语言快。因为在C语言中定义一个int型的变量的话,其值是存储在内存中的。
|
一派护法 十九级 |
【程序3】 ORG 0x7c00 JMP entry DB 0x90 DB "HELLOIPL" DW 512 DB 1 DW 1 DB 2 DW 224 DW 2880 DB 0xf0 DW 9 DW 18 DW 2 DD 0 DD 2880 DB 0, 0, 0x29 DD 0xffffffff DB "HELLO-OS " DB "FAT12 " RESB 18 ; 这是程序开始执行的地方 entry: MOV AX, 0 MOV SS, AX MOV SP, 0x7c00 MOV DS, AX MOV ES, AX MOV DL, 0 ; DL的初值为0 ; 准备好显示字符的所需参数: AH和BX MOV AH, 0x0e MOV BX, 15 putloop: ; 显示八进制数的第一位 ; AL = DL >> 3 + '0' MOV AL, DL SHR AL, 3 ; 位右移3位 ADD AL, '0' INT 0x10 ; 显示八进制数的第二位 ; AL = DL & 0x07 MOV AL, DL AND AL, 0x07 ADD AL, '0' INT 0x10 ; 如果DL==63, 则跳转到fin CMP DL, 63 JE fin ; 否则显示逗号和空格并使DL的值加1,然后跳回putloop MOV AL, ',' INT 0x10 MOV AL, ' ' INT 0x10 ADD DL, 1 JMP putloop ; 无限循环 fin: HLT JMP fin RESB 0x7dfe-$ DB 0x55, 0xaa 【运行结果】
|
一派护法 十九级 |
昨天下午我试了很久,DIV除法指令在这里不知为何没有任何作用,执行后AH和AL的值还是没变。所以本来想做十进制数0~99的输出的,结果以失败告终了。
|