nand2teris_lecture04
Nand2teris04 机器语言
机器语言概要:
机器语言分为两种,汇编语言和二进制语言
机器语言主要操控着三个底层硬件:处理器cpu,内存memory和寄存器register
机器语言利用处理器和寄存器来操控内存
处理器,内存和寄存器的简单介绍:
- 内存:储存数据和指令的硬件设备,数据和指令均为二进制数。
- 处理器:对数据和指令进行一些操作,比如从内存或寄存器中存入或取出数据或指令,将数据进行算术操作,指令进行逻辑操作。
- 寄存器:临时存放一些数据或指令,方便处理器计算
两种机器语言
- 二进制语言:在16位计算机上,左边4位代表着cpu的操作编码,后面的12位标识此次操作的操作数。
- 汇编语言:由于二进制语言晦涩难懂,采用助记符的形式代表二进制语言。助记符可以表示底层硬件和二进制操作。例如1010001100011001这串二进制代码中,前面4位操作编码1010可用add助记符表示,后面12位可用R0~R15助记符来表示,整串代码可表示为Add R3,R1,R9
不同的计算机,其汇编语法也各不相同,下面介绍通用的语法。
寻址方式
- 直接寻址:直接表示一个指定内存单元的地址,这在A寄存器中很常用
例:LOAD R1,67 // R1 🡨 Memory [67]
- 立即寻址:将常数加载到寄存器中,而不是作为内存单元的地址,这在D寄存器中很常用
例:LOAD R1,67 // R1 🡨 67
- 间接寻址:不直接的表示一个指定内存单元的地址
例:ADD x,6,7 // x = 6+7
LOAD R1,x // R1 🡨 Memory [x]
控制流程
命令之间通过控制流程来跳转。控制流程包括循环,条件语句,无条件跳转和子程序调用
Hack机器语言概述
- Hack机器语言(汇编语言和二进制语言)能通过指令轻易的操控Hack机器中的两个寄存器 D寄存器A寄存器
D寄存器存储数据值,A寄存器存储数据值,数据值和指令值的地址
- Hack机器语言的指令有两种操控方式:算术指令和逻辑指令
在算术指令中,CPU会将计算的返回结果返回到D寄存器暂存,
例如:D = Memory [516] -1 CPU从内存地址为516的内存单元(这里假设为数据内存)中取值,将计算结果存储到D寄存器。这条算术指令也可以表示为D = M -1,这里M表示的也是内存单元的值
-
- 算术指令详解:

算术指令前后可分为三个部分
- 计算什么
- 将计算后的值存储到什么地方
- 下一步做什么
-
- 计算什么
-
算术指令(以下简称C指令)的comp域是规定要计算的内容。Comp域通过128个函数指明了ALU该如何计算,计算什么。
例如:1110 0011 1000 0000 表示让ALU进行D-1的操作,即D寄存器当前值减1.

(当a=1)
Comp助记符
-
-
- 将计算后的值存储到什么地方
-
C指令的dest域决定着计算结果所要保存的目的地,

d1决定着是否将计算结果存入A寄存器(存入地址),d2决定着是否将计算结果存入到D寄存器(存入数值),d3决定着是否将计算结果存入到M内存单元。
例如:0000 0000 0000 0111 //@7
1111 1101 1101 1000 //M,D = M+1
表示的就是将A寄存器的值,设为7,然后将内存单元memory[7]的值加1,存入内存单元和D寄存器
-
-
- 下一步做什么
-
C指令的jump域告诉计算机下一步将执行什么命令。Jump域的三个位:
J1规定:当ALU输出值小于0,发生跳转
J2规定:当ALU输出值等于0,发生跳转
J3规定:当ALU输出值大于0,发生跳转

所以当C指令的comp域执行完成后,将执行结果保存到dest域,执行结果的大小与jump域的条件结合,决定当前指令需不需要跳转到下一条指令。下一条指令的地址由A寄存器保留。
Hack机器语言
二进制语言
汇编语言
逻辑指令
算术指令
数据内存
指令内存
-
- 逻辑指令详解
在逻辑指令中,cpu会按照A寄存器中存储的值(地址值),从指令内存中取值,执行一系列例如jump跳转,while循环的逻辑操作,从一条指令跳转到另一条指令,指令的地址由A寄存器保存。
A寄存器中的值通过A指令设置。
(图为A指令介绍)

例如@5,将5的二进制形式存储到A寄存器中。表示Memory[5],
汇编符号
汇编语言中除了汇编指令,另一板块就是汇编符号,下面介绍三种汇编符号
- 预定义符号:
虚拟寄存器:R0~R15用来代表0到15号RAM地址
预定义指针:SP、LCL、ARG、THIS、THAT也被用来代表0到4号RAM地址
I/O指针:SCREEN和KBD被用来表示RAM地址16384(0x4000)和24576(0x600),这两个地址也分别表示屏幕和键盘内存地址
- 标签符号:
用户自定义的符号,由伪命令“(xxx)”来声明,符号只能被自定义一次。用来标记goto命令跳转的地址。Xxx的RAM地址代表着下一条指令的地址,这在后面的汇编编译器章节有说明。自定义的符号可以在汇编程序中的任何地方使用。
(由于伪指令xxx经过汇编器翻译后不会产生任何二进制代码,所以称为伪指令)
- 变量符号:
在汇编程序中任何用户定义的符号xxx,如果它不是预定义符号,也不是使用“(xxx)”的标签符号,那么就被看作是变量,并被汇编程序赋予独立的内存地址,从RAM地址16,即0x0010开始。
关于汇编语言和二进制语言的联系
- 汇编语言文件以.asm命名,二进制语言文件以.jack命名。
- 汇编语言文件由文本行组成,每一行代表着一条指令或者一个符号定义;二进制语言文件也由文本行组成,第n行二进制码被存储到指令内存RAM的地址为n的单元(RAM[n])
一些补充声明:
- 常数(constants)和符号( symbols):常数必须是非负的而且总是用十进制表示。用户自定义的符号可以是任何字母、数字、下划线(_ )、点(.)、美元符号($)、 冒号(:)构成的字符串,但它不能以数字开头。
- 注释以双斜线 (//) 开头,并到本行结束符之前(不换行)的文本被认为是注释,不被程序执行。
- 空格空格字符及空行也被程序忽略。
- 大小写:所有的汇编助记符必须大写。其他的比如用户自定义标签(label) 和变量名
则要区分大小写。一般是标签大写,变量名小写。

浙公网安备 33010602011771号