一个将汇编指令子集转换成机器码的小工具
1. 该汇编指令子集的规范
a. 支持的指令集
b. 使用的寄存器
可以使用的寄存器有32个,命名和对应的编码为:
r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 |
---|---|---|---|---|---|---|---|
00000 | 00001 | 00010 | 00011 | 00100 | 00101 | 00110 | 00111 |
r8 | r9 | r10 | r11 | r12 | r13 | r14 | r15 |
01000 | 01001 | 01010 | 01011 | 01100 | 01101 | 01110 | 01111 |
r16 | r17 | r18 | r19 | r20 | r21 | r22 | r23 |
10000 | 10001 | 10010 | 10011 | 10100 | 10101 | 10110 | 10111 |
r24 | r25 | r26 | r27 | r28 | r29 | r30 | r31 |
11000 | 11001 | 11010 | 11011 | 11100 | 11101 | 11110 | 11111 |
注:其中r0是ZERO寄存器,它的值永远是0.
c. 指令格式
所有指令都是32位字长,格式如下:
I型指令(lw, sw, addi, andi,beqz):
注:1. beqz的汇编格式为beqz r1,i
,其中r1表示的是rs寄存器,i表示的是immediate,它的 rd寄存器默认是ZERO寄存器,它跳转的地址为pc+1+immediate
;
2. 对于另外4个 I 型指令,汇编格式为 symbol r1,r2,i
,其中r1表示rd寄存器,r2表示rs寄 存器,i 表示immediate。
R型指令(add, sub, and):
注:R型指令的汇编格式为symbol r1,r2,r3
,其中r1表示rd寄存器,r2表示rs1寄存器,r3表示 rs2寄存器。
J型指令(j, halt, noop):
注:1. 对于指令j,无条件跳转的地址为 pc+1+offset
;
2. 对于halt,noop指令,offset的值为0。
d. 用该汇编子集编写的程序示例
求Fibonacci数列
addi r9,r9,1 ;set r9=1
addi r1,r1,10 ;set r1=r10, r1 is counter
loop add r10,r8,r9 ;r10 = r8+r9
addi r8,r9,0 ;r8=r9
addi r9,r10,0 ;r9=r10
sw r10,r2,0 ;store r10, use r2 as offset
addi r2,r2,1 ;offset++
addi r1,r1,-1 ;counter--
beqz r1,end ;loop
j loop
end halt
e. 书写规范
- 可选的标号,例如上例中的 loop 和 end
- 指令名称
- 指令字段:寄存器、立即数、标号
- 注释,由分号开始,到行末结束
f. 上例汇编指令转成的机器指令
556335105
539033610
17387552
556269568
558432256
-1404436480
541196289
539099135
270532609
201326584
67108864
为了更好地分析这些机器指令,整理如下:
addi r9,r9,1 ;556335105 (001000|01001|01001|0000000000000001)
addi r1,r1,10 ;539033610 (001000|00001|00001|0000000000001010)
loop add r10,r8,r9 ;17387552 (000000|01000|01001|01010|00000100000)
addi r8,r9,0 ;556269568 (001000|01001|01000|0000000000000000)
addi r9,r10,0 ;558432256 (001000|01010|01001|0000000000000000)
sw r10,r2,0 ;-1404436480 (101011|00010|01010|0000000000000000)
addi r2,r2,1 ;541196289 (001000|00010|00010|0000000000000001)
addi r1,r1,-1 ;539099135 (001000|00001|00001|1111111111111111)
beqz r1,end ;270532609 (000100|00001|00000|0000000000000001)
j loop ;201326584 (000010|11111111111111111111111000)
end halt ;67108864 (000001|00000000000000000000000000)
2. 该汇编小工具处理汇编文件的流程
第一遍扫描汇编文件:
- 提取指令装入指令队列;
- 将出现标记符号装进标记符号容器
第二遍扫描指令队列:
读取指令第一个符号
- 若第一个符号在指令名称集里:
进行指令合法性检查,不合法则报错
合法则将该指令翻译为机器指令,输出到文件
-
若第一个符号不在指令名称集里:
去掉指令第一个符号,进行指令合法性检查,不合法则报错
合法则将该指令翻译为机器指令,输出到文件
3. 该汇编器的使用方法
内容格式如下的汇编文件:
fibonacci.asm
addi r9,r9,1 ;set r9=1
addi r1,r1,10 ;set r1=r10, r1 is counter
loop add r10,r8,r9 ;r10 = r8+r9
addi r8,r9,0 ;r8=r9
addi r9,r10,0 ;r9=r10
sw r10,r2,0 ;store r10, use r2 as offset
addi r2,r2,1 ;offset++
addi r1,r1,-1 ;counter--
beqz r1,end ;loop
j loop
end halt
使用如下命令:
assembler.exe <asm file> <machine-code file>
将会得到一个内容格式如下的输出文件:
556335105
539033610
17387552
556269568
558432256
-1404436480
541196289
539099135
270532609
201326584
67108864