注意:本文经过原作者授权转译,转载请标明出处
原文地址:http://mrjester.hapisan.com/04_MC68/Sect01Part03/Index.html
条件允许建议阅读原文,网上非中文资料还是较多,当作锻炼英文岂不美哉
翻译若有不足之处欢迎批评指正
译文:
"计算机之于计算机科学,正如望远镜之于天文学" ---- 艾兹格·迪杰特斯拉 (Edsger W. Dijkstra, 1930-2002),结构程序设计之父,伟大的计算机先驱
简介
m68k 有一系列你可以使用的"指令" (Instruction,像是命令),你可以使用这些指令来完成你想做的事,比如修改数值,控制处理器读写内存等等
在这一节我将带你们去康康一个指令的基本特点
助记符
在计算时,指令都是以二进制被处理器读取的,比如这条指令的二进制形式:
0011 0000 0011 1100 0000 0100 1111 0000
很明显这么长串的二进制很难去记忆,我们不会直接去跟它们打交道,这时就需要汇编语言
登场了
事实上我们用一些"助记符",它们是一些简单的英文单词,用以代替上面那条二进制长串,下面是把刚刚那条指令用助记符表示的:
move.w #$04F0, d0
你可能已经注意到我把指令按照颜色分割成了不同的部分,其中橙色move
是"命令" (command),绿色.w
是"长度",蓝色#$04F0
是"源操作数",紫色d0
是"目的操作数"
-
命令:有很多很多种,比如
move
,add
,sub
,divu
,mulu
,bra
,jmp
等等,分别表示一些数学计算或是程序流控制的功能 -
长度:用来指定你当前指令想要使用的数值长度,比如
.b
表示字节
(byte),.w
表示字
(word),.l
表示长字
(long-word) - 源操作数:表示数据会从哪里读取,或者是哪里的数据将会被使用
- 目的操作数:表示哪里的数据会被修改,移动或是操作
那么让我们来康康一条你可能会发现很容易理解的指令:
move.b #$2C, $0000001E
这条指令会把字节
2C
移动到内存中偏移量
为0000001E
的位置,正如你所见它所做的就是它字面上描述的那样
m68k 处理完这条指令之后,内存中00000001E
处的字节就会被修改为2C
:
|偏移量 |0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |A |B |C |D |E |F
|----------|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---
|00000000|00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00
|00000010|00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |2C |00
|00000020|00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00
|00000030|00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00
|...
就是这么简单
当你去汇编你的代码时,汇编程序会把你的助记符
move.w #$04F0, d0
全部转换成二进制:
0011 0000 0011 1100 0000 0100 1111 0000
以便于m68k 能够读取
标记#
和$
你可能留意到在刚才的那条指令中有出现#
和$
这种符号,其中$
是告诉汇编程序这个数是十六进制
(hex) 数,如果不加上$
的话,就表示十进制
数,比如:
move.b #32, $0000001E
汇编程序会把32
(此时是十进制
) 转换成0010 0000
(二进制
),而0010 0000
转化成十六进制
是20
,所以在指令中写32
就相当于写$20
,如果你想在指令中直接写二进制
数,可以用%
符号:
move.b #%00100000, $0000001E
move.b #$20, $0000001E
move.b #32, $0000001E
上面这几条指令的意思是一样的,第一行是二进制
版本(%
),第二行是十六进制
版本($
),最后一行是十进制
版本,在这系列教程中我们更多的使用二进制
和十六进制
版本来让你们更好的去理解
而对于#
符号,目的是要告诉汇编程序,这个数是立即数
(immediate) 而不是偏移量
.... emmmm那么立即数
又是个啥?别急,我们先来康康一个例子:
move.b $00000010, $0000002D
这条指令将会读取偏移量
00000010
处的字节
,然后把它复制到0000002D
的位置,如果00000010
位置的值是49
,那么0000002D
位置的值也会在这条指令执行后变成49
:
偏移量 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
00000000 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
00000010 | 49 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
00000020 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 49 | 00 | 00 |
00000030 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
... |
现在让我们再回到立即数
(immediate) 这个名词,据我所知,它只是"纯粹的数"的一个比较好听的名字,通过使用#
符号来告诉m68k 这个数不是偏移量
/地址
熟悉《计算机组成原理》的同学可能已经明白了,加了#
的寻址方式是立即数寻址
,而不加#
的是直接寻址
目录
上一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 壹 - 基础介绍 | 2. 内存存储
下一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 壹 - 基础介绍 | 4. 寄存器