part A
[root@edb3963640a6 misc]#./yas sum.ys
[root@edb3963640a6 misc]# ./yis sum.yo
./yas 和 ./yis 是汇编语言编译器和模拟器的命令行工具。
./yas 是一个汇编语言编译器,它将汇编语言代码转换为可执行的二进制文件。./yas sum.ys 将sum.ys文件编译成了sum.yo可执行文件。
./yis 是一个模拟器,它用于执行和模拟已编译的二进制文件。运行./yis sum.yo 将执行sum.yo文件并输出结果。
这两个工具通常用于汇编语言的开发和调试过程中。
part B
使用的Y86-64指令需要先使用irmovq指令将一个寄存器设置为常量,然后使用addq指令将这个值添加到目标寄存器。假设我们想要添加一个新的指令iaddq
参考知乎网友写的 iaddq指令的处理阶段, 使用hcl语言写出这个流程。
seq-full.hcl 文件:
执行 make VERSION=full
在asumi.yo 文件中调用iaddq指令
执行 ./ssim -t …/y86-code/asumi.yo
[root@edb3963640a6 seq]# ./ssim -t ../y86-code/asumi.yo
Y86-64 Processor: seq-full.hcl
137 bytes of code read
IF: Fetched irmovq at 0x0. ra=----, rb=%rsp, valC = 0x100
IF: Fetched call at 0xa. ra=----, rb=----, valC = 0x38
Wrote 0x13 to address 0xf8
IF: Fetched irmovq at 0x38. ra=----, rb=%rdi, valC = 0x18
IF: Fetched irmovq at 0x42. ra=----, rb=%rsi, valC = 0x4
IF: Fetched call at 0x4c. ra=----, rb=----, valC = 0x56
Wrote 0x55 to address 0xf0
IF: Fetched xorq at 0x56. ra=%rax, rb=%rax, valC = 0x0
IF: Fetched andq at 0x58. ra=%rsi, rb=%rsi, valC = 0x0
IF: Fetched jmp at 0x5a. ra=----, rb=----, valC = 0x83
IF: Fetched jne at 0x83. ra=----, rb=----, valC = 0x63
IF: Fetched mrmovq at 0x63. ra=%r10, rb=%rdi, valC = 0x0
IF: Fetched addq at 0x6d. ra=%r10, rb=%rax, valC = 0x0
IF: Fetched iaddq at 0x6f. ra=----, rb=%rdi, valC = 0x8
IF: Fetched iaddq at 0x79. ra=----, rb=%rsi, valC = 0xffffffffffffffff
IF: Fetched jne at 0x83. ra=----, rb=----, valC = 0x63
IF: Fetched mrmovq at 0x63. ra=%r10, rb=%rdi, valC = 0x0
IF: Fetched addq at 0x6d. ra=%r10, rb=%rax, valC = 0x0
IF: Fetched iaddq at 0x6f. ra=----, rb=%rdi, valC = 0x8
IF: Fetched iaddq at 0x79. ra=----, rb=%rsi, valC = 0xffffffffffffffff
IF: Fetched jne at 0x83. ra=----, rb=----, valC = 0x63
IF: Fetched mrmovq at 0x63. ra=%r10, rb=%rdi, valC = 0x0
IF: Fetched addq at 0x6d. ra=%r10, rb=%rax, valC = 0x0
IF: Fetched iaddq at 0x6f. ra=----, rb=%rdi, valC = 0x8
IF: Fetched iaddq at 0x79. ra=----, rb=%rsi, valC = 0xffffffffffffffff
IF: Fetched jne at 0x83. ra=----, rb=----, valC = 0x63
IF: Fetched mrmovq at 0x63. ra=%r10, rb=%rdi, valC = 0x0
IF: Fetched addq at 0x6d. ra=%r10, rb=%rax, valC = 0x0
IF: Fetched iaddq at 0x6f. ra=----, rb=%rdi, valC = 0x8
IF: Fetched iaddq at 0x79. ra=----, rb=%rsi, valC = 0xffffffffffffffff
IF: Fetched jne at 0x83. ra=----, rb=----, valC = 0x63
IF: Fetched ret at 0x8c. ra=----, rb=----, valC = 0x0
IF: Fetched ret at 0x55. ra=----, rb=----, valC = 0x0
IF: Fetched halt at 0x13. ra=----, rb=----, valC = 0x0
32 instructions executed
Status = HLT
Condition Codes: Z=1 S=0 O=0
Changed Register State:
%rax: 0x0000000000000000 0x0000abcdabcdabcd
%rsp: 0x0000000000000000 0x0000000000000100
%rdi: 0x0000000000000000 0x0000000000000038
%r10: 0x0000000000000000 0x0000a000a000a000
Changed Memory State:
0x00f0: 0x0000000000000000 0x0000000000000055
0x00f8: 0x0000000000000000 0x0000000000000013
ISA Check Succeeds
[root@edb3963640a6 seq]#
执行 testssim
[root@edb3963640a6 y86-code]# make testssim
../seq/ssim -t asum.yo > asum.seq
../seq/ssim -t asumr.yo > asumr.seq
../seq/ssim -t cjr.yo > cjr.seq
../seq/ssim -t j-cc.yo > j-cc.seq
../seq/ssim -t poptest.yo > poptest.seq
../seq/ssim -t pushquestion.yo > pushquestion.seq
../seq/ssim -t pushtest.yo > pushtest.seq
../seq/ssim -t prog1.yo > prog1.seq
../seq/ssim -t prog2.yo > prog2.seq
../seq/ssim -t prog3.yo > prog3.seq
../seq/ssim -t prog4.yo > prog4.seq
../seq/ssim -t prog5.yo > prog5.seq
../seq/ssim -t prog6.yo > prog6.seq
../seq/ssim -t prog7.yo > prog7.seq
../seq/ssim -t prog8.yo > prog8.seq
../seq/ssim -t ret-hazard.yo > ret-hazard.seq
grep "ISA Check" *.seq
asum.seq:ISA Check Succeeds
asumr.seq:ISA Check Succeeds
cjr.seq:ISA Check Succeeds
j-cc.seq:ISA Check Succeeds
poptest.seq:ISA Check Succeeds
prog1.seq:ISA Check Succeeds
prog2.seq:ISA Check Succeeds
prog3.seq:ISA Check Succeeds
prog4.seq:ISA Check Succeeds
prog5.seq:ISA Check Succeeds
prog6.seq:ISA Check Succeeds
prog7.seq:ISA Check Succeeds
prog8.seq:ISA Check Succeeds
pushquestion.seq:ISA Check Succeeds
pushtest.seq:ISA Check Succeeds
ret-hazard.seq:ISA Check Succeeds
rm asum.seq asumr.seq cjr.seq j-cc.seq poptest.seq pushquestion.seq pushtest.seq prog1.seq prog2.seq prog3.seq prog4.seq prog5.seq prog6.seq prog7.seq prog8.seq ret-hazard.seq
测试iaddq 指令:
make SIM=…/seq/ssim TFLAGS=-i
汇编
irmovq 指令
irmovq指令是x86汇编语言中的一条指令,用于将立即数(即常数)加载到寄存器中。这个指令主要用于将一个立即数加载到目标寄存器中,而不是从内存中读取数据。
irmovq指令的具体格式如下:
irmovq 立即数, 寄存器
其中立即数表示要加载到寄存器的常数值,寄存器表示要将常数加载到的目标寄存器。
举个例子,如果我们要将立即数0x123456789abcdef0加载到寄存器%rdx中,我们可以使用irmovq指令:
irmovq $0x123456789abcdef0, %rdx
这条指令的作用是将立即数0x123456789abcdef0加载到寄存器%rdx中。
需要注意的是,irmovq指令是x86汇编语言中的一条特定指令,具体的用法和语法可能会因为不同的处理器架构或者汇编语言规范而有所不
同。
mrmovq 指令
mrmovq指令是x86汇编语言中的一条指令,用于将内存中的数据加载到寄存器中。这个指令主要用于从内存中读取数据,然后将其加载到寄存器中。
mrmovq指令的具体格式如下:
mrmovq 地址, 寄存器
其中地址表示要读取数据的内存地址,寄存器表示要将读取的数据加载到的目标寄存器。
举个例子,如果我们要将内存地址0xf7bdc0c3处的数据加载到寄存器%rax中,我们可以使用mrmovq指令:
mrmovq 0xf7bdc0c3, %rax
这条指令的作用是将内存地址0xf7bdc0c3处的数据加载到寄存器%rax中。
需要注意的是,mrmovq指令是x86汇编语言中的一条特定指令,具体的用法和语法可能会因为不同的处理器架构或者汇编语言规范而有所不同。
环境问题
gcc 找不到 lfl
yum install flex
yum install flex-devel