HOME> 梅西世界杯图片> 汇编语言 之屏幕显示输出Hello World
{$vo.文章标题}
{$vo.文章标题}

汇编语言 之屏幕显示输出Hello World

admin
6138

使用的系统是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) $表示开始,$$表示结束。

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