网站 建设原则,做网站最贵,o2o商城网站搭建,wordpress 视频课堂文章目录 前言一、A部分sum .ys#xff1a;迭代求和链表元素写一个Y86-64的程序和。rsum .递归求和链表元素copy.ys 复制将源块复制到目标块 二、B部分三、C部分实现iaddq指令 总结 前言
一个本硕双非的小菜鸡#xff0c;备战24年秋招。刚刚看完CSAPP#xff0c;真是一本神… 文章目录 前言一、A部分sum .ys迭代求和链表元素写一个Y86-64的程序和。rsum .递归求和链表元素copy.ys 复制将源块复制到目标块 二、B部分三、C部分实现iaddq指令 总结 前言
一个本硕双非的小菜鸡备战24年秋招。刚刚看完CSAPP真是一本神书啊遂尝试将它的Lab实现并记录期间心酸历程。 代码下载
官方网站CSAPP官方网站 这道题下载完了记得不是完事了还有一句话需要执行
unix cd sim
unix make clean; make如果执行make clean; make出现了报错如 可参考这位大佬的解决方案林夕丶
以下是官方文档翻译 在这个实验室中您将学习流水线Y86-64处理器的设计和实现优化它和基准程序以最大化性能。允许您对基准测试程序进行任何语义保留转换或者对流水线处理器进行增强或者两者都进行。当您完成了实验室的工作后您将会对影响程序性能的代码和硬件之间的交互产生强烈的欣赏。 这个实验室被分为三个部分每个部分都有自己的把手。 在A部分中您将编写一些简单的Y86-64程序并熟悉Y86-64工具。 在B部分中您将使用一个新的指令来扩展SEQ模拟器。 这两个部分将为您为实验室的核心C部分做准备在那里您将优化Y86-64基准程序和处理器设计。 一、A部分
您将在本部分的目录sim/misc中工作。 您的任务是编写和模拟以下三个Y86-64程序。这些程序的所需行为由示例中的examples.c函数定义。一定要在每个程序的开头把你的名字和ID放在注释中。您可以测试您的程序首先用程序YAS组装它们然后用指令集模拟器YIS运行它们。 在所有的Y86-64函数中您应该遵循x86-64约定来传递函数参数、使用寄存器和使用堆栈。这包括保存和恢复您使用的任何被调用的保存寄存器。
人话把sim/misc/examples.c里面的仨函数用Y86-64程序写出来 参考书中图4.8 ps我感觉用处不大啊就是手写Y86-64的汇编程序呗难怪我看做的人也不是很多。并不打算多费时间在这上就参考其他大佬的了 具体详见知乎大佬的解析早睡晚起
sum .ys迭代求和链表元素写一个Y86-64的程序和。
即对链表中的元素进行迭代求和。您的程序应该由一些设置堆栈结构、调用一个函数、然后停止的代码组成。在这种情况下函数应该是Y86-64代码(sum list)在功能上等同于C sum list和图1中的列表函数。使用以下三元素列表测试程序
# Sample linked list
.align 8
ele1:
.quad 0x00a
.quad ele2
ele2:
.quad 0x0b0
.quad ele3
ele3:
.quad 0xc00
.quad 01 /* linked list element */
2 typedef struct ELE {
3 long val;
4 struct ELE *next;
5 } *list_ptr;
6
7 /* sum_list - Sum the elements of a linked list */
8 long sum_list(list_ptr ls)
9 {
10 long val 0;
11 while (ls) {
12 val ls-val;
13 ls ls-next;
14 }
15 return val;
16 }
17
18 /* rsum_list - Recursive version of sum_list */
19 long rsum_list(list_ptr ls)
20 {
21 if (!ls)
22 return 0;
23 else {
24 long val ls-val;
25 long rest rsum_list(ls-next);
26 return val rest;
27 }
28 }
29
30 /* copy_block - Copy src to dest and return xor checksum of src */
31 long copy_block(long *src, long *dest, long len)
32 {
33 long result 0;
34 while (len 0) {
35 long val *src;
36 *dest val;
37 result ˆ val;
38 len--;
39 }
40 return result;
41 }
/*Y86-64解决方案函数的C个版本。参见sim/misc/examples.c*/代码
# sum_list - Sum the elements of a linked list
# author: Deconx# Execution begins at address 0.pos 0irmovq stack, %rsp # Set up stack pointercall main # Execute main programhalt # Terminate program# Sample linked list.align 8
ele1:.quad 0x00a.quad ele2
ele2:.quad 0x0b0.quad ele3
ele3:.quad 0xc00.quad 0main:irmovq ele1,%rdicall sum_listret# long sum_list(list_ptr ls)
# start in %rdi
sum_list:irmovq $0, %raxjmp testloop:mrmovq (%rdi), %rsiaddq %rsi, %raxmrmovq 8(%rdi), %rditest:andq %rdi, %rdijne loopret# Stack starts here and grows to lower addresses.pos 0x200
stack:
注意应在stack下方空一行否则汇编器会报错。 然后按操作手册来新建一个sum.ys文件并把代码放入。 执行 ./yas sum.ys ./yis sum.yo
看到%rax是cba就是成功了 rsum .递归求和链表元素
编写一个Y86-64程序 rsum.ys递归地和链表的元素。这个代码应该类似于sum.ys的代码除了它应该使用一个函数rsum list递归地求和一个数字列表的列表如C函数rsum list所示 在图1中列出。使用用于测试列表相同的三元素列表测试程序list.ys.
代码
# /* rsum_list - Recursive version of sum_list */
# author: Deconx# Execution begins at address 0.pos 0irmovq stack, %rsp # Set up stack pointercall main # Execute main programhalt # Terminate program# Sample linked list.align 8
ele1:.quad 0x00a.quad ele2
ele2:.quad 0x0b0.quad ele3
ele3:.quad 0xc00.quad 0main:irmovq ele1,%rdicall rsum_listret# long sum_list(list_ptr ls)
# start in %rdi
rsum_list:andq %rdi, %rdije return # if(!ls)mrmovq (%rdi), %rbx # val ls-valmrmovq 8(%rdi), %rdi # ls ls-nextpushq %rbxcall rsum_list # rsum_list(ls-next)popq %rbxaddq %rbx, %rax # val restret
return:irmovq $0, %raxret# Stack starts here and grows to lower addresses.pos 0x200
stack:
注意应在stack下方空一行否则汇编器会报错。 然后按操作手册来新建一个rsum.ys文件并把代码放入。 执行 ./yas rsum.ys ./yis rsum.yo
看到%rax是cba就是成功了 copy.ys 复制将源块复制到目标块
编写一个程序copy.ys将单词块从内存的一个部分复制到另一个内存非重叠区域计算所有复制单词的校验和Xor。 您的程序应该由设置堆栈框架、调用函数副本的代码组成阻止然后停止。该函数应该在功能上等同于C函数copy block如图1所示。使用以下三个元素的源块和目标块测试程序
.align 8
# Source block
src:
.quad 0x00a
.quad 0x0b0
.quad 0xc00
# Destination block
dest:
.quad 0x111
.quad 0x222
.quad 0x333代码
/* copy_block - Copy src to dest and return xor checksum of src */
# author: Deconx# Execution begins at address 0.pos 0irmovq stack, %rsp # Set up stack pointercall main # Execute main programhalt # Terminate program# Sample.align 8
# Source block
src:.quad 0x00a.quad 0x0b0.quad 0xc00# Destination block
dest:.quad 0x111.quad 0x222.quad 0x333main:irmovq src, %rdi # srcirmovq dest, %rsi # destirmovq $3, %rdx # lencall copy_blockret# long copy_block(long *src, long *dest, long len)
# src in %rdi
# dest in %rsi
# len in %rdx
copy_block:irmovq $8, %r8irmovq $1, %r9irmovq $0, %raxandq %rdx, %rdxjmp test
loop:mrmovq (%rdi), %r10 # val *src1addq %r8, %rdi # srcrmmovq %r10, (%rsi) # *dest valaddq %r8, %rsi # destxorq %r10, %rax # result ^ valsubq %r9, %rdx # len--. Set CC
test:jne loop # Stop when 0ret# Stack starts here and grows to lower addresses.pos 0x200
stack:
这道题几乎与4-7完全相同
注意应在stack下方空一行否则汇编器会报错。 然后按操作手册来新建一个copy_block.ys文件并把代码放入。 执行 ./yas copy_block.ys ./yis copy_block.yo
看到%rax是cba就是成功了 二、B部分
您将在这部分的目录sim/seq中工作。 B部分中的任务是扩展SEQ处理器以支持iaddq在家庭作业问题4.51和4.52中描述。要添加此说明 您将修改文件的seq-full.hcl它实现了CS APP3e教科书中描述的SEQ版本。此外它还包含了您 的解决方案所需要的一些常量的声明。 HCL文件必须以包含以下信息的标题注释开头
你的名字和身份证。对iaddq指令所需的计算方法的描述。使用CS APP3e文本中图4.18中的irmovq和OPq的描述作为指南。 构建和测试您的解决方案 一旦你完成了修改序列的全部。hcl文件然后你将需要基于这个hcl文件建立一个新的SEQ模拟器ssim的实例然后测试它 建立一个新的模拟器。你可以使用make来构建一个新的SEQ模拟器 unix make VERSIONfull 这构建了一个使用您在seq-full中指定的控制逻辑的ssim版本。要保存键入操作您可以在Makefile中给与VERSIONfull。 在一个简单的Y86-64程序上测试你的解决方案。对于您的初始测试我们建议在TTY模式下运行简单的程序如asumi.yo测试iaddq并将结果与ISA模拟进行比较 unix ./ssim -t …/y86-code/asumi.yo 如果ISA测试失败那么您应该通过以GUI模式单步进模拟器来调试实现 unix ./ssim -g …/y86-code/asumi.yo 使用基准测试程序重新测试您的解决方案。一旦你的模拟器能够正确地执行小程序那么你就可以自动在Y86-64基准测试程序上测试它。…/y86-code: unix (cd …/y86-code; make testssim) 这将在基准测试程序上运行ssim并通过将生成的处理器状态与来自高级ISA模拟的状态进行比较来检查其正确性。请注意这些程序都没有测试所添加的指令。您只是在确保您的解决方案没有为原始指令注入错误。查看文件…/y86-code/README文件了解更多细节。 执行回归测试。一旦您能够正确地执行基准测试程序那么您就应该在…/ptest中运行广泛的回归测试集。要测试除iaddq之外的所有内容并leave unix (cd …/ptest; make SIM…/seq/ssim) 要测试iaddq的实现 unix (cd …/ptest; make SIM…/seq/ssim TFLAGS-i) 有关SEQ模拟器的更多信息请参阅关于Y86-64处理器模拟器simguide.pdf的分发CS APP3e指南。
1 /*
2 * ncopy - copy src to dst, returning number of positive ints
3 * contained in src array.
4 */
5 word_t ncopy(word_t *src, word_t *dst, word_t len)
6 {
7 word_t count 0;
8 word_t val;
9
10 while (len 0) {
11 val *src;
12 *dst val;
13 if (val 0)
14 count;
15 len--;
16 }
17 return count;
18 }
/*图2ncopy函数的C版本。请参阅sim/pipe/ncopy.c*/这块就不越俎代庖了大家看大佬的就好大佬答案 测试方法
make VERSIONfull
cd seq/
./ssim -t ../y86-code/asumi.yoY86-64 Processor: seq-full.hcl
cd ../ptest; make SIM../seq/ssim TFLAGS-i三、C部分
您将在本部分的目录sim/pipe中工作。 图2中的ncopy函数将一个len-元素整数数组src复制到一个不重叠的dst中返回src中包含的正整数的计数。图3显示了ncopy的基线Y86-64版本。文件pipe-full.hcl包含一个针对PIPE的HCL代码的副本以及一个常量值IIADDQ的声明。 您在C部分中的任务是修改ncopy.ys和pipe-full.hcl的目标是制作ncopy.ys。跑得越快越好。 你将提交两个文件pipe-full.hcl和ncopy.ys。每个文件都应该以一个包含以下信息的标题注释开头 你的名字和身份证。 对您的代码的高级描述。在每种情况下描述您如何以及为什么修改代码。
您可以自由地做任何您想要的修改并有以下限制
你的ncopy.ys函数必须适用于任意大小的数组。您可能会试图通过简单地编码64个复制指令来硬连接64个元素数组的解决方案但这将是一个坏主意因为我们将根据其在任意数组上的性能对您的解决方案进行分级。你的ncopy.ys函数必须与YIS一起正确运行。通过正确地复制我们的意思是它必须正确地复制src块并返回以%rax表示正确的正整数数。ncopy文件的组装版本的长度不能超过1000字节。您可以使用提供的脚本check-len.pl检查嵌入了ncopy函数的任何程序的长度unix ./check-len.pl ncopy.yo你的pipe-full.hcl实现必须通过中的回归测试…/y86-code和 …/ptest。没有测试iaddq的-i标志。
除此之外如果你认为iaddq指令会有帮助你就可以自由地执行iaddq指令。您可以对ncopy进行任何保留语义的转换。它的功能如重新排序指令用单个指令替换指令组删除一些指令以及添加其他指令。您可能会发现在CS APP3e的第5.8节中阅读关于循环展开的信息很有用。
1 ##################################################################
2 # ncopy.ys - Copy a src block of len words to dst.
3 # Return the number of positive words (0) contained in src.
4 #
5 # Include your name and ID here.
6 #
7 # Describe how and why you modified the baseline code.
8 #
9 ##################################################################
10 # Do not modify this portion
11 # Function prologue.
12 # %rdi src, %rsi dst, %rdx len
13 ncopy:
14
15 ##################################################################
16 # You can modify this portion
17 # Loop header
18 xorq %rax,%rax # count 0;
19 andq %rdx,%rdx # len 0?
20 jle Done # if so, goto Done:
21
22 Loop: mrmovq (%rdi), %r10 # read val from src...
23 rmmovq %r10, (%rsi) # ...and store it to dst
24 andq %r10, %r10 # val 0?
25 jle Npos # if so, goto Npos:
26 irmovq $1, %r10
27 addq %r10, %rax # count
28 Npos: irmovq $1, %r10
29 subq %r10, %rdx # len--
30 irmovq $8, %r10
31 addq %r10, %rdi # src
32 addq %r10, %rsi # dst
33 andq %rdx,%rdx # len 0?
34 jg Loop # if so, goto Loop:
35 ##################################################################
36 # Do not modify the following section of code
37 # Function epilogue.
38 Done:
39 ret
40 ##################################################################
41 # Keep the following label at the end of your function
42 End:
/*ncopy函数的基线Y86-64版本。请参阅sim/pipe/ncopy.ys*/解答
实现iaddq指令
pipe-full.hcl改动部分可参考PartB
# Is instruction valid?
bool instr_valid f_icode in { INOP, IHALT, IRRMOVQ, IIRMOVQ, IRMMOVQ, IMRMOVQ,IOPQ, IJXX, ICALL, IRET, IPUSHQ, IPOPQ, IIADDQ};# Does fetched instruction require a regid byte?
bool need_regids f_icode in { IRRMOVQ, IOPQ, IPUSHQ, IPOPQ, IIRMOVQ, IRMMOVQ, IMRMOVQ, IIADDQ};# Does fetched instruction require a constant word?
bool need_valC f_icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ, IJXX, ICALL, IIADDQ};## What register should be used as the B source?
word d_srcB [D_icode in { IOPQ, IRMMOVQ, IMRMOVQ , IIADDQ} : D_rB;D_icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP;1 : RNONE; # Dont need register
];## What register should be used as the E destination?
word d_dstE [D_icode in { IRRMOVQ, IIRMOVQ, IOPQ, IIADDQ} : D_rB;D_icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP;1 : RNONE; # Dont write any register## Select input A to ALU
word aluA [E_icode in { IRRMOVQ, IOPQ } : E_valA;E_icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ, IIADDQ} : E_valC;E_icode in { ICALL, IPUSHQ } : -8;E_icode in { IRET, IPOPQ } : 8;# Other instructions dont need ALU
];## Select input B to ALU
word aluB [E_icode in { IRMMOVQ, IMRMOVQ, IOPQ, ICALL, IPUSHQ, IRET, IPOPQ, IIADDQ} : E_valB;E_icode in { IRRMOVQ, IIRMOVQ } : 0;# Other instructions dont need ALU
];## Should the condition codes be updated?
bool set_cc E_icode (E_icode IOPQ || E_icode IIADDQ)# State changes only during normal operation!m_stat in { SADR, SINS, SHLT } !W_stat in { SADR, SINS, SHLT };在sim/pipe输入以下命令测试
./psim -t ../y86-code/asumi.yo
(cd ../ptest;make SIM../pipe/psim TFLAGS-i)
(cd ../ptest;make SIM../pipe/psim)测试成功 通过这两个命令测试CPE
./correctness.pl
./benchmark.pl得 出了点问题改完iaddrq指令后CPE全都变成小于1了。。。不知道为啥 网上也没找到原因重新替换也不好使。 总结
这一章比较乱我的重心也没放在这里。最近事太多心理上也十分的烦躁、焦虑。希望以后可以恢复过来然后我再次跟这道题抗争到底我能行的