标签:
李忠老师的《x86汇编语言:从实模式到保护模式》中第五章到第七章的部分,每一章在讲述知识点的同时,分别使用了三种不同的显示字符的方法,加上调用BIOS的10h中 断的方法,这里做出一次简单梳理:
一:第五章,最基础的直接用mov 的方法
代码如下:
1 ;代码清单5-1 2 ;文件名:c05_mbr.asm 3 ;文件说明:硬盘主引导扇区代码 4 ;创建日期:2011-3-31 21:15 5 6 mov ax,0xb800 ;指向文本模式的显示缓冲区 7 mov es,ax 8 9 ;以下显示字符串"Label offset:" 10 mov byte [es:0x00],‘L‘ 11 mov byte [es:0x01],0x07 12 mov byte [es:0x02],‘a‘ 13 mov byte [es:0x03],0x07 14 mov byte [es:0x04],‘b‘ 15 mov byte [es:0x05],0x07 16 mov byte [es:0x06],‘e‘ 17 mov byte [es:0x07],0x07 18 mov byte [es:0x08],‘l‘ 19 mov byte [es:0x09],0x07 20 mov byte [es:0x0a],‘ ‘ 21 mov byte [es:0x0b],0x07 22 mov byte [es:0x0c],"o" 23 mov byte [es:0x0d],0x07 24 mov byte [es:0x0e],‘f‘ 25 mov byte [es:0x0f],0x07 26 mov byte [es:0x10],‘f‘ 27 mov byte [es:0x11],0x07 28 mov byte [es:0x12],‘s‘ 29 mov byte [es:0x13],0x07 30 mov byte [es:0x14],‘e‘ 31 mov byte [es:0x15],0x07 32 mov byte [es:0x16],‘t‘ 33 mov byte [es:0x17],0x07 34 mov byte [es:0x18],‘:‘ 35 mov byte [es:0x19],0x07 36 37 mov ax,number ;取得标号number的偏移地址 38 mov bx,10 39 40 ;设置数据段的基地址 41 mov cx,cs 42 mov ds,cx 43 44 ;求个位上的数字 45 mov dx,0 46 div bx 47 mov [0x7c00+number+0x00],dl ;保存个位上的数字 48 49 ;求十位上的数字 50 xor dx,dx 51 div bx 52 mov [0x7c00+number+0x01],dl ;保存十位上的数字 53 54 ;求百位上的数字 55 xor dx,dx 56 div bx 57 mov [0x7c00+number+0x02],dl ;保存百位上的数字 58 59 ;求千位上的数字 60 xor dx,dx 61 div bx 62 mov [0x7c00+number+0x03],dl ;保存千位上的数字 63 64 ;求万位上的数字 65 xor dx,dx 66 div bx 67 mov [0x7c00+number+0x04],dl ;保存万位上的数字 68 69 ;以下用十进制显示标号的偏移地址 70 mov al,[0x7c00+number+0x04] 71 add al,0x30 72 mov [es:0x1a],al 73 mov byte [es:0x1b],0x04 74 75 mov al,[0x7c00+number+0x03] 76 add al,0x30 77 mov [es:0x1c],al 78 mov byte [es:0x1d],0x04 79 80 mov al,[0x7c00+number+0x02] 81 add al,0x30 82 mov [es:0x1e],al 83 mov byte [es:0x1f],0x04 84 85 mov al,[0x7c00+number+0x01] 86 add al,0x30 87 mov [es:0x20],al 88 mov byte [es:0x21],0x04 89 90 mov al,[0x7c00+number+0x00] 91 add al,0x30 92 mov [es:0x22],al 93 mov byte [es:0x23],0x04 94 95 mov byte [es:0x24],‘D‘ 96 mov byte [es:0x25],0x07 97 98 infi: jmp near infi ;无限循环 99 100 number db 0,0,0,0,0 101 102 times 203 db 0 103 db 0x55,0xaa
这里采用的最基础的做法,就是对字符进行一个一个的处理。先将显示缓存区的地址0xb800赋给es寄存器,然后通过 mov byte[es:0x00],‘L‘ 的形式,来处理后续的字符。这种方法较为简单,这里不再赘述。
二:第六章,采用了批量处理的方法
代码如下:
1 ;代码清单6-1 2 ;文件名:c06_mbr.asm 3 ;文件说明:硬盘主引导扇区代码 4 ;创建日期:2011-4-12 22:12 5 6 jmp near start 7 8 mytext db ‘L‘,0x07,‘a‘,0x07,‘b‘,0x07,‘e‘,0x07,‘l‘,0x07,‘ ‘,0x07,‘o‘,0x07, 9 ‘f‘,0x07,‘f‘,0x07,‘s‘,0x07,‘e‘,0x07,‘t‘,0x07,‘:‘,0x07 10 number db 0,0,0,0,0 11 12 start: 13 mov ax,0x7c0 ;设置数据段基地址 14 mov ds,ax 15 16 mov ax,0xb800 ;设置附加段基地址 17 mov es,ax 18 19 cld 20 mov si,mytext 21 mov di,0 22 mov cx,(number-mytext)/2 ;实际上等于 13 23 rep movsw 24 25 ;得到标号所代表的偏移地址 26 mov ax,number 27 28 ;计算各个数位 29 mov bx,ax 30 mov cx,5 ;循环次数 31 mov si,10 ;除数 32 digit: 33 xor dx,dx 34 div si 35 mov [bx],dl ;保存数位 36 inc bx 37 loop digit 38 39 ;显示各个数位 40 mov bx,number 41 mov si,4 42 show: 43 mov al,[bx+si] 44 add al,0x30 45 mov ah,0x04 46 mov [es:di],ax 47 add di,2 48 dec si 49 jns show 50 51 mov word [es:di],0x0744 52 53 jmp near $ 54 55 times 510-($-$$) db 0 56 db 0x55,0xaa
这里采用的办法是批量传送,后续用loop循环挨个处理。这样的写法明显比上一种写法要高明一些,减少了工作量。这段代码中值得注意的地方是 mov si,mytext (其中mytext是声明的字符的地址),这里值得留意的原因之一是在做显示时间的编码中,有过下列这样的写法,所以会格外的留心。
1 org 7c00h 2 start1: 3 4 5 mov ax, cs ; 置其他段寄存器值与CS相同 6 mov ds, ax ; 数据段 7 mov es, ax 8 9 mov bl, 10h 10 mov bp, Message1 11 12 mov ah, 02h 13 int 1ah 14 15 xor ax, ax 16 mov al, ch 17 div bl 18 add al, 0x30 19 mov [es:bp+2], al 20 add ah, 0x30 21 mov [es:bp+3], ah 22 23 xor ax, ax 24 mov al, cl 25 div bl 26 add al, 0x30 27 mov [es:bp+5], al 28 add ah, 0x30 29 mov [es:bp+6], ah 30 31 xor ax, ax 32 mov al, dh 33 div bl 34 add al, 0x30 35 mov [es:bp+8], al 36 add ah, 0x30 37 mov [es:bp+9], ah 38 39 mov dh, 3 40 mov dl, 0 41 mov ax, 1301h ; 功能号 42 mov bp, Message1 43 mov cx, MessageLength1 44 mov bx, 0007h 45 int 10h 46 47 ; ret 48 49 Message1: 50 db ‘ 00:00:00‘ 51 MessageLength1 equ ($-Message1) 52 53 times 510-($-$$) db 0 ; 用0填充引导扇区剩下的空间 54 db 55h, 0aah ; 引导扇区结束标志
(上面的那段代码的功能是调用BIOS中断显示系统时间)这段代码中对于“00:00:00”的处理方法,代码二中批量处理si处的mytext字段有异曲同工之妙,这里mark一下。
关于代码二中显示数字的方法,是用到了loop循环。先将数字按照“除以10”的方法得到每一位的值,然后将其加上0x30(有关ASCII的知识可解释这一点是为什么),然后将最终值赋予 依次递增的显存。直到将之前处理的每一位数字都显示出来,over.
三:第七章,使用栈来操作
四:调用BIOS的10h中断来显示字符
标签:
原文地址:http://www.cnblogs.com/liugl7/p/4418900.html