Hello World程序
本文最初发表于2015-8-??,是由别的地方迁移过来的
本文利用改写内存的办法在屏幕中央显示“Hello world”字符串。
首先我们需要了解80*25彩色字符模式显示缓冲区的结构。
〉〉内存中B8000H~BFFFFH的32KB内存空间是80*25彩色字符模式的显示缓冲区。
〉〉一个字符要在该缓冲区中显示需要一个字的空间。低字节保存字符的ASCII码,高字节保存字符的显示属性。
〉〉需要(80*2)*25 = 4000Byte的内存空间来存放一页的内容。
〉〉该缓冲区分为8页,通常显示第0页的内容。
其次是要知道如何实现将字符写入内存并显示出来。
〉〉ASCII码:即美国标准信息交换代码,用一个字节来表示。具体的表格请看附录!
〉〉显示缓冲区的属性:属性由一个字节表示,格式如下:
第/位: 7 6 5 4 3 2 1 0
表示 BL R G B I R G B
(R:红色 G:绿色 B:蓝色, 0~2位:前景 3:高亮 4~6:背景 7 :闪烁)(闪烁只有在全屏模式下才有效)
例如显示一个字符为红底白字的属性:01000111B
〉〉显示一个字符的结构 (ASCII码+属性)
〉〉写入内存的方法
mov 内存地址X,ASCII码
mov 内存地址X+1,属性代码
直接写入就可以显示
注意:
汇编语言显示Hello World的方法不止这一种
本程序必须在DOS下才能看见,如果系统是Windows vista 以上的可能不会显示,Windows xp 下有时看不见。具体可以安装一个虚拟机,推荐Microsoft Virtual PC 2007,下载地址请看附注。
现在来看代码:
; 程序原理:将字符串从数据段逐字符拷贝到显示空间里,因为要显示在中央,以缓冲区第
;0页的第一个地址为段地址,计算得出其第一个字符的ASCII码存放位置应为B800:07C0H
;在拷贝的同时设定属性,共一个循环。 assume cs:code data segment
db 'Hello world!' ; 定义字符串
data ends code segment start: ; 程序入口 mov ax,data
mov ds,ax ; 初始化数据段
mov ax,0b800h
mov es,ax ; 用附加寄存器初始化显示段 mov cx,12d ;循环次数
mov si,0h ; 初始化数据段偏移地址
mov di,0h ; 初始化显示段偏移地址 put: ; 逐个字符输出
mov al,ds:[si] ; 把字符的ASCII码放入al中
mov es:7c0h[di],al ; 从al中读取ASCII码写入显示段
mov word ptr es:7c1h[di],01000111b ; 设置属性
inc si ; 移动到数据段的下一个字符
add di,2d ; 移动到显示段的下一个字符显示空间
loop put ; 执行循环 mov ax,4c00h
int 21h ; 程序返回 code ends end start
程序执行的结果:
使用Microsoft Virtual PC 2007 并安装MS-DOS 6.22
尝试:优化代码并编译执行。
ASCII码表(来源:http://www.asciima.com/ )
00000000 |
0 |
00 |
NUL(null) |
空字符 |
00000001 |
1 |
01 |
SOH(start of headling) |
标题开始 |
00000010 |
2 |
02 |
STX (start of text) |
正文开始 |
00000011 |
3 |
03 |
ETX (end of text) |
正文结束 |
00000100 |
4 |
04 |
EOT (end of transmission) |
传输结束 |
00000101 |
5 |
05 |
ENQ (enquiry) |
请求 |
00000110 |
6 |
06 |
ACK (acknowledge) |
收到通知 |
00000111 |
7 |
07 |
BEL (bell) |
响铃 |
00001000 |
8 |
08 |
BS (backspace) |
退格 |
00001001 |
9 |
09 |
HT (horizontal tab) |
水平制表符 |
00001010 |
10 |
0A |
LF (NL line feed, new line) |
换行键 |
00001011 |
11 |
0B |
VT (vertical tab) |
垂直制表符 |
00001100 |
12 |
0C |
FF (NP form feed, new page) |
换页键 |
00001101 |
13 |
0D |
CR (carriage return) |
回车键 |
00001110 |
14 |
0E |
SO (shift out) |
不用切换 |
00001111 |
15 |
0F |
SI (shift in) |
启用切换 |
00010000 |
16 |
10 |
DLE (data link escape) |
数据链路转义 |
00010001 |
17 |
11 |
DC1 (device control 1) |
设备控制1 |
00010010 |
18 |
12 |
DC2 (device control 2) |
设备控制2 |
00010011 |
19 |
13 |
DC3 (device control 3) |
设备控制3 |
00010100 |
20 |
14 |
DC4 (device control 4) |
设备控制4 |
00010101 |
21 |
15 |
NAK (negative acknowledge) |
拒绝接收 |
00010110 |
22 |
16 |
SYN (synchronous idle) |
同步空闲 |
00010111 |
23 |
17 |
ETB (end of trans. block) |
传输块结束 |
00011000 |
24 |
18 |
CAN (cancel) |
取消 |
00011001 |
25 |
19 |
EM (end of medium) |
介质中断 |
00011010 |
26 |
1A |
SUB (substitute) |
替补 |
00011011 |
27 |
1B |
ESC (escape) |
溢出 |
00011100 |
28 |
1C |
FS (file separator) |
文件分割符 |
00011101 |
29 |
1D |
GS (group separator) |
分组符 |
00011110 |
30 |
1E |
RS (record separator) |
记录分离符 |
00011111 |
31 |
1F |
US (unit separator) |
单元分隔符 |
00100000 |
32 |
20 |
(space) |
空格 |
00100001 |
33 |
21 |
! |
|
00100010 |
34 |
22 |
" |
|
00100011 |
35 |
23 |
# |
|
00100100 |
36 |
24 |
$ |
|
00100101 |
37 |
25 |
% |
|
00100110 |
38 |
26 |
& |
|
00100111 |
39 |
27 |
' |
|
00101000 |
40 |
28 |
( |
|
00101001 |
41 |
29 |
) |
|
00101010 |
42 |
2A |
* |
|
00101011 |
43 |
2B |
+ |
|
00101100 |
44 |
2C |
, |
|
00101101 |
45 |
2D |
- |
|
00101110 |
46 |
2E |
. |
|
00101111 |
47 |
2F |
/ |
|
00110000 |
48 |
30 |
0 |
|
00110001 |
49 |
31 |
1 |
|
00110010 |
50 |
32 |
2 |
|
00110011 |
51 |
33 |
3 |
|
00110100 |
52 |
34 |
4 |
|
00110101 |
53 |
35 |
5 |
|
00110110 |
54 |
36 |
6 |
|
00110111 |
55 |
37 |
7 |
|
00111000 |
56 |
38 |
8 |
|
00111001 |
57 |
39 |
9 |
|
00111010 |
58 |
3A |
: |
|
00111011 |
59 |
3B |
; |
|
00111100 |
60 |
3C |
< |
|
00111101 |
61 |
3D |
= |
|
00111110 |
62 |
3E |
> |
|
00111111 |
63 |
3F |
? |
|
01000000 |
64 |
40 |
@ |
|
01000001 |
65 |
41 |
A |
|
01000010 |
66 |
42 |
B |
|
01000011 |
67 |
43 |
C |
|
01000100 |
68 |
44 |
D |
|
01000101 |
69 |
45 |
E |
|
01000110 |
70 |
46 |
F |
|
01000111 |
71 |
47 |
G |
|
01001000 |
72 |
48 |
H |
|
01001001 |
73 |
49 |
I |
|
01001010 |
74 |
4A |
J |
|
01001011 |
75 |
4B |
K |
|
01001100 |
76 |
4C |
L |
|
01001101 |
77 |
4D |
M |
|
01001110 |
78 |
4E |
N |
|
01001111 |
79 |
4F |
O |
|
01010000 |
80 |
50 |
P |
|
01010001 |
81 |
51 |
Q |
|
01010010 |
82 |
52 |
R |
|
01010011 |
83 |
53 |
S |
|
01010100 |
84 |
54 |
T |
|
01010101 |
85 |
55 |
U |
|
01010110 |
86 |
56 |
V |
|
01010111 |
87 |
57 |
W |
|
01011000 |
88 |
58 |
X |
|
01011001 |
89 |
59 |
Y |
|
01011010 |
90 |
5A |
Z |
|
01011011 |
91 |
5B |
[ |
|
01011100 |
92 |
5C |
\ |
|
01011101 |
93 |
5D |
] |
|
01011110 |
94 |
5E |
^ |
|
01011111 |
95 |
5F |
_ |
|
01100000 |
96 |
60 |
` |
|
01100001 |
97 |
61 |
a |
|
01100010 |
98 |
62 |
b |
|
01100011 |
99 |
63 |
c |
|
01100100 |
100 |
64 |
d |
|
01100101 |
101 |
65 |
e |
|
01100110 |
102 |
66 |
f |
|
01100111 |
103 |
67 |
g |
|
01101000 |
104 |
68 |
h |
|
01101001 |
105 |
69 |
i |
|
01101010 |
106 |
6A |
j |
|
01101011 |
107 |
6B |
k |
|
01101100 |
108 |
6C |
l |
|
01101101 |
109 |
6D |
m |
|
01101110 |
110 |
6E |
n |
|
01101111 |
111 |
6F |
o |
|
01110000 |
112 |
70 |
p |
|
01110001 |
113 |
71 |
q |
|
01110010 |
114 |
72 |
r |
|
01110011 |
115 |
73 |
s |
|
01110100 |
116 |
74 |
t |
|
01110101 |
117 |
75 |
u |
|
01110110 |
118 |
76 |
v |
|
01110111 |
119 |
77 |
w |
|
01111000 |
120 |
78 |
x |
|
01111001 |
121 |
79 |
y |
|
01111010 |
122 |
7A |
z |
|
01111011 |
123 |
7B |
{ |
|
01111100 |
124 |
7C |
| |
|
01111101 |
125 |
7D |
} |
|
01111110 |
126 |
7E |
~ |
|
01111111 |
127 |
7F |
DEL (delete) |
删除 |
Hello World程序的更多相关文章
- JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议
软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...
- 【小程序分享篇 一 】开发了个JAVA小程序, 用于清除内存卡或者U盘里的垃圾文件非常有用
有一种场景, 手机内存卡空间被用光了,但又不知道哪个文件占用了太大,一个个文件夹去找又太麻烦,所以我开发了个小程序把手机所有文件(包括路径下所有层次子文件夹下的文件)进行一个排序,这样你就可以找出哪个 ...
- 微信小程序开发心得
微信小程序也已出来有一段时间了,最近写了几款微信小程序项目,今天来说说感受. 首先开发一款微信小程序,最主要的就是针对于公司来运营的,因为,在申请appid(微信小程序ID号)时候,需要填写相关的公司 ...
- node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理
一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...
- 微信应用号(小程序)开发IDE配置(第一篇)
2016年9月22日凌晨,微信宣布“小程序”问世,当然只是开始内测了,微信公众平台对200个服务号发送了小程序内测邀请.那么什么是“小程序”呢,来看微信之父怎么说 看完之后,相信大家大概都有些明白了吧 ...
- 编写高质量代码:改善Java程序的151个建议(第5章:数组和集合___建议75~78)
建议75:集合中的元素必须做到compareTo和equals同步 实现了Comparable接口的元素就可以排序,compareTo方法是Comparable接口要求必须实现的,它与equals方法 ...
- 【探索】在 JavaScript 中使用 C 程序
JavaScript 是个灵活的脚本语言,能方便的处理业务逻辑.当需要传输通信时,我们大多选择 JSON 或 XML 格式. 但在数据长度非常苛刻的情况下,文本协议的效率就非常低了,这时不得不使用二进 ...
- 通过Jexus 部署 dotnetcore版本MusicStore 示例程序
ASPNET Music Store application 是一个展示最新的.NET 平台(包括.NET Core/Mono等)上使用MVC 和Entity Framework的示例程序,本文将展示 ...
- Code Review 程序员的寄望与哀伤
一个程序员,他写完了代码,在测试环境通过了测试,然后他把它发布到了线上生产环境,但很快就发现在生产环境上出了问题,有潜在的 bug. 事后分析,是生产环境的一些微妙差异,使得这种 bug 场景在线下测 ...
- 使用 .NET WinForm 开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序
直接切入正题,这是我09年到11年左右业余时间编写的项目,最初的想法很简单,做一个能拖拖拽拽就直接生成应用程序的工具,不用写代码,把能想到的业务操作全部封装起来,通过配置的方式把这些业务操作组织起来运 ...
随机推荐
- svn上传文件
转自:http://zhouhaitao.iteye.com/blog/1122918 如何将指定文件或文件夹直接提交到svn指定目录? 如何将指定文件或文件夹直接提交到svn指定目录? 一般我们都是 ...
- 个人收集(转载)CSS中 display:none和visibility:hidden的区别
visibility和display两个属性都有隐藏元素的功能,display:none和visibility:hidden的区别,简单的总结一句话就是:visibility:hidden隐藏,但在浏 ...
- AS3深拷贝数据对象(2)深拷贝VO对象
Topic:对于用户自定义的VO对象进行深拷贝,一种VO对象的某属性可能是另一种VO对象的实例. 方法1:通过传说中的“AS3隐藏特性——ByteArray.writeObject和readObjec ...
- Flex Alert的匿名回调函数如何得到正确的this
Flex中经常使用Alert来弹出提示或确认窗口,为了方便省事,会直接用匿名函数作为回调,但有时如果要调用外部的this,你会发现匿名函数中的this无法指向外部父类,可以使用e.target获取pa ...
- 覆盖原有div或者Input的鼠标移上去描述
<input onmouseover="this.title='我是描述内容'" />
- python常见环境安装
pyinotify安装git clone https://github.com/seb-m/pyinotify.gitcd pyinotify/python setup.py install 安装py ...
- linux下LAMP环境搭建尝试
最近,学习搭建了LAMP服务环境,中间遇到了很多问题,经过不断摸索总算得以解决.为了大家少走弯路,现将相关经验进行总结. linux下软件安装分为自动安装和手动安装两种,自动安装借助工具如yum等,自 ...
- php接口post提交方法 。
方法一,用 file_get_contents function send_post($url, $post_data) { //$postdata = http_build_query($post_ ...
- 多XML追加操作
假设要统计当前系统中所有的试卷进行分析,试卷是以XML格式存储的,所有这就需要将所有零散的XML文件整合起来,处理成一个完整的XML文件,进行分析, 下面是简单额处理方法: 当前XML文件格式: &l ...
- 【spring 6】Spring和Hibernate的整合:编程式事务
一.编程式事务简介 在 Spring 出现以前,编程式事务管理对基于 POJO 的应用来说是唯一选择.用过 Hibernate 的人都知道,我们需要在代码中显式调用beginTransaction() ...