作者共发了7篇帖子。 内容转换:不转换▼
 
点击 回复
301 6
【汇编语言程序】在软盘启动画面上用循环显示”0123456789“
一派护法 十九级
1楼 发表于:2016-2-3 17:03
先看最终运行效果:

一派护法 十九级
2楼 发表于:2016-2-3 17:05
复制光盘里的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 ; 启动区标志,表示软盘上有启动程序

一派护法 十九级
3楼 发表于:2016-2-3 17:08
最后,依次双击文件夹里的asm.bat,makeimg.bat和run.bat文件,即可运行程序。

其中asm.bat把汇编语言程序编译为512字节的ipl.bin文件,这是软盘的头512字节的启动区。然后用makeimg.bat把该启动区变成软盘iso映像文件,最后run.bat启动虚拟机运行这个软盘上的启动程序。
一派护法 十九级
4楼 发表于:2016-2-3 17:33
【程序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
【运行结果】

一派护法 十九级
5楼 发表于:2016-2-3 17:39
由于DL是CPU上的一个寄存器,不是内存上的一个存储单元,所以这个程序执行起来肯定比C语言快。因为在C语言中定义一个int型的变量的话,其值是存储在内存中的。
一派护法 十九级
6楼 发表于:2016-2-3 19:58
【程序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
【运行结果】

一派护法 十九级
7楼 发表于:2016-2-4 23:08
昨天下午我试了很久,DIV除法指令在这里不知为何没有任何作用,执行后AH和AL的值还是没变。所以本来想做十进制数0~99的输出的,结果以失败告终了。

回复帖子

内容:
用户名: 您目前是匿名发表
验证码:
(快捷键:Ctrl+Enter)
 

本帖信息

点击数:301 回复数:6
评论数: ?
作者:巨大八爪鱼
最后回复:巨大八爪鱼
最后回复时间:2016-2-4 23:08
 
©2010-2024 Arslanbar Ver2.0
除非另有声明,本站采用知识共享署名-相同方式共享 3.0 Unported许可协议进行许可。