使用的系统是manjaro linux。使用的工具是emu8086模拟器,是安装在windows xp 系统里面的(用wine也能运行),真实的运行环境是windows xp 虚拟机,语法格式为masm。因为本人已经很久没用windows,而汇编的开发工具windows是比linux好的,特别是这个emu8086模拟器,非常的好用。但是目前来看emu8086是最好用的开发环境了,不光具有调试功能,而且集成了内存视图,文件列表(lst文件)等非常使用的工具,emu8086使用的是masm语法。其实本人更喜欢nasm的语法格式。

开始正题:

用汇编在显示器上实现hello world其实也不难。下面给出代码并解释。下面给出masm格式的代码实现,在后面会给出一份nasm格式的实现。其实都差不多。

 

 

 


; You may customize this and other start-up templates; 
; The location of this template is c:\emu8086\inc\0_com_template.txt

mov ax,0xb800
mov ds,ax  ;跳转到显存的位置   

mov  [0x00],0x41    ;字符a
mov  [0x01],0x04    ;颜色为红色

mov  [0x02],'s'
mov  [0x03],0x14    ;随便取色

mov  [0x04],'s'
mov  [0x05],0x24

mov  [0x06],'e'
mov  [0x07],0x34

mov  [0x08],'m'
mov  [0x09],0x44

mov  [0x0a],'b'
mov  [0x0b],0x54      

mov  [0x0c],'l'
mov  [0x0d],0x64

mov  [0x0e],'y'
mov [0x1f],0x74        

mov  [0x10],'.'
mov [0x11],0x84        

db 510-(0x5f) dup(0)
db 0x55,0xaa

首先显示文本是需要用到显卡的显存的,其实就是一块存储器,一般有几M。对应内存地址的一段地址空间。这个地址空间的起点是0xb800。这个是固定的。别的设备也会站一段属于自己的地址空间。mov ax,0xb800 mov ds,ax就是跳转到显存的起始位置。

字符的结构由两个byte组成。第一个byte表示ascii表对应的编号比如a对应的编号是0x41,也可以直接写成'a'.

第二个byte表示颜色,颜色的格式是krgb irgb。前4位表示背景色,后4位表示前景色。k表示是否闪烁,1表示闪烁,0表示不闪烁。i表示是否是灰度,1表示是,0表示否。

例如0x04,0对应0000,也就是krgb全是0,表示背景色纯黑不闪烁。4对应0100,表示无灰度的红也就是irgb中的r为1,其它都为0。

 

最后要说一些最后两行。

先说说最后一行 db 0x55,0xaa。db表示手动写入内容。这里手动写入0x55和0xaa。这两个两个值是什么意思?这段程序是要写到主引导扇区的,主引导扇区规定最后两个字节就是这两个,最为结束的标记。主引导扇区有512个字节。而且主引导扇区需要填满。所以512-2还有510个字节。需要减去我们写的代码占用的大小。我们怎么知道我们写的代码在内存中的大小呢?可以通过lst文件查看。这个lst数据是可以通过工具生成的。emu8086自带这个功能直接帮你生成。位置在调试器的view->listing

EMU8086 GENERATED LISTING. MACHINE CODE <- SOURCE.
 
noname.bin_ -- emu8086 assembler version: 4.08  
 
[ 2021-3-25  --  18:31:09 ] 
 
===================================================================================================
[LINE]     LOC: MACHINE CODE                          SOURCE
===================================================================================================
 
[   1]        :                                       
[   2]        :                                       ; You may customize this and other start-up templates;
[   3]        :                                       ; The location of this template is c:\emu8086\inc\0_com_template.txt
[   4]        :                                       
[   5]    0000: B8 00 B8                              mov ax,0xb800
[   6]    0003: 8E D8                                 mov ds,ax
[   7]        :                                       
[   8]    0005: C6 06 00 00 41                        mov  [0x00],0x41    ;字符A
[   9]    000A: C6 06 01 00 04                        mov  [0x01],0x04    ;颜色为红色
[  10]        :                                       
[  11]    000F: C6 06 02 00 73                        mov  [0x02],'s'
[  12]    0014: C6 06 03 00 14                        mov  [0x03],0x14
[  13]        :                                       
[  14]    0019: C6 06 04 00 73                        mov  [0x04],'s'
[  15]    001E: C6 06 05 00 24                        mov  [0x05],0x24
[  16]        :                                       
[  17]    0023: C6 06 06 00 65                        mov  [0x06],'e'
[  18]    0028: C6 06 07 00 34                        mov  [0x07],0x34
[  19]        :                                       
[  20]    002D: C6 06 08 00 6D                        mov  [0x08],'m'
[  21]    0032: C6 06 09 00 44                        mov  [0x09],0x44
[  22]        :                                       
[  23]    0037: C6 06 0A 00 62                        mov  [0x0a],'b'
[  24]    003C: C6 06 0B 00 54                        mov  [0x0b],0x54
[  25]        :                                       
[  26]    0041: C6 06 0C 00 6C                        mov  [0x0c],'l'
[  27]    0046: C6 06 0D 00 64                        mov  [0x0d],0x64
[  28]        :                                       
[  29]    004B: C6 06 0E 00 79                        mov  [0x0e],'y'
[  30]    0050: C6 06 1F 00 74                        mov [0x1f],0x74
[  31]        :                                       
[  32]    0055: C6 06 10 00 2E                        mov  [0x10],'.'
[  33]    005A: C6 06 11 00 84                        mov [0x11],0x84
[  34]        :                                       
[  35]        :                                       ;times 510-($-$$) db 0
[  36]    005F: 00 00 00 00 00 00 00 00 00 00 00 00   db 510-(0x5f) dup(0)
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00 00 00 00 00 00 
                00 00 00 00 00 00 00                
[  37]    01FE: 55 AA                                 db 0x55,0xaa
[  38]        :                                       
[  39]        :                                       
[  40]        :                                       
[  41]        :                                       
[  42]        :                                       
[  43]        :                                       
[  44]        :                                       
[  45]        :                                       
[  46]        :                                       
 
===================================================================================================
 




===================================================================================================

注意标号为36的地方,地址值为5f,也就是表示我们前面显示文字的代码占用了5f个字节的地址空间,所以db 510-(0x5f) dup(0)这行代码就非常好解释了。dup表示重复执行次数为510-(0x5f),十进制和二进制是可以混合写的。dup(0) 表示写入的内容为0,就是将剩余的空间全部填充为0.

下面给出nasm格式的代码,其实差不多只是语法不太一样。nasm可以指定值的单位是byte还是word  1word=2byte.重复使用times而不是dup。

 

mov ax,0xb800
mov ds,ax   

mov byte [0x00],0x41    ;字符A
mov byte [0x01],0x04    ;颜色为红色

mov byte  [0x02],'s'
mov byte  [0x03],0x14

mov byte [0x04],'s'
mov  byte [0x05],0x24

mov byte  [0x06],'e'
mov byte [0x07],0x34

mov byte [0x08],'m'
mov byte [0x09],0x44

mov byte [0x0a],'b'
mov byte [0x0b],0x54      

mov  byte [0x0c],'l'
mov byte [0x0d],0x64

mov byte [0x0e],'y'
mov byte [0x1f],0x74        

mov byte [0x10],'.'
mov byte [0x11],0x84        

times 510-($-$$) db 0
;db 510-(0x5f) dup(0)
db 0x55,0xaa

每次都要计算非常的麻烦,更简单的方法就是设置标志位,在开始的地方设置start标志位,名字可以随便取。结束的地方设置另一个标志位两个相减。


start:
mov ax,0xb800
mov ds,ax   

mov  [0x00],0x41    ;字符A
mov  [0x01],0x04    ;颜色为红色
            
...

current:     

db (current-start) dup(0)

还有跟简单的方法就是使用提供的特殊符号来表示

db ($-$$) dup(0) $表示开始,$$表示结束。

最后的显示效果,是有不同颜色的哟!虽然颜色很丑。。。

 

 

 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐