Write a Y86-64 program sum.ys that iteratively sums the elements of a linked list. Your program should consist of some code that sets up the stack structure, invokes a function, and then halts. In this case,the function should be Y86-64 code for a function (sum list) that is functionally equivalent to the C sum list function in Figure 1.
写一个Y86-64程序sum.ys,迭代地对链表的元素求和。你的程序应该由一些代码组成,这些代码设置堆栈结构,调用函数,然后停止。在这种情况下,该函数应该是Y86-64代码,用于在功能上等同于图1中的C sum list函数的函数(sum list)。使用以下三元素列表测试程序:
sum list
1 2 3 4 5 6 7 8 9
longsum_list(list_ptr ls) { long val = 0; while (ls) { val += ls->val; ls = ls->next; } return val; }
# Execution begins at address 0 .pos 0 irmovq stack, %rsp call main halt # Sample linked list .align 8 ele1: .quad 0x00a .quad ele2 ele2: .quad 0x0b0 .quad ele3 ele3: .quad 0xc00 .quad 0
# get main main: irmovq ele1, %rdi call sum_list # sum(list_ptr ls) ret # long sum_list(list_ptr ls) # start in %rdi sum_list: xorq %rax,%rax #rax-->sum_list=0 andq %rdi ,%rdi # test jmp test
loop: mrmovq (%rdi),%rsi addq %rsi,%rax mrmovq 8(%rdi),%rdi # rdi--->next andq %rdi,%rdi # test rdi test: jne loop # rdi==0 ret ret
.pos 0x200 stack:
然后使用yas和yis进行测试,若%rax==0xcba则成功!
rsum.ys
rsum.ys: Recursively sum linked list elements Write a Y86-64 program rsum.ys that recursively sums the elements of a linked list. This code should be similar to the code in sum.ys, except that it should use a function rsum list that recursively sums a list of numbers, as shown with the C function rsum list in Figure 1. Test your program using the same three-element list you used for testing list.ys.
# get main main: irmovq ele1, %rdi call rsum_list ret rsum_list: andq %rdi ,%rdi je return mrmovq (%rdi),%rsi mrmovq 8(%rdi),%rdi pushq %rsi call rsum_list popq %rsi addq %rsi,%rax ret return: irmovq $0x0, %rax ret .pos 0x200 stack:
写完后测试提交,$rax的值正确!
copy.ys
copy.ys: Copy a source block to a destination block Write a program (copy.ys) that copies a block of words from one part of memory to another (non-overlapping area) area of memory, computing the checksum (Xor) of all the words copied. Your program should consist of code that sets up a stack frame, invokes a function copy block, and then halts. The function should be functionally equivalent to the C function copy block shown in Figure 1. Test your program using the following three-element source and destination blocks:
longcopy_block(long *src, long *dest, long len) { long result = 0; while (len > 0) { long val = *src++; *dest++ = val; result ^= val; len--; } return result; }
Your task in Part B is to extend the SEQ processor to support the iaddq, described in Homework problems 4.51 and 4.52. To add this instructions, you will modify the file seq-full.hcl, which implements the version of SEQ described in the CS:APP3e textbook. In addition, it contains declarations of some constants that you will need for your solution.
# Does fetched instruction require a regid byte?获取的指令是否需要regid字节? bool need_regids = icode in { IRRMOVQ, IOPQ, IPUSHQ, IPOPQ, IIRMOVQ, IRMMOVQ, IMRMOVQ, IIADDQ};
# Does fetched instruction require a constant word? bool need_valC = icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ, IJXX, ICALL,IIADDQ };
Decode Stage
srcB:rB
dstE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
## What register should be used as the B source? word srcB = [ icode in { IOPQ, IRMMOVQ, IMRMOVQ,IIADDQ } : rB; icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP; 1 : RNONE; # Don't need register ];
## What register should be used as the E destination? word dstE = [ icode in { IRRMOVQ } && Cnd : rB; icode in { IIRMOVQ, IOPQ,IIADDQ} : rB; icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP; 1 : RNONE; # Don't write any register ];
## Select input A to ALU word aluA = [ icode in { IRRMOVQ, IOPQ } : valA; icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ,IIADDQ } : valC; icode in { ICALL, IPUSHQ } : -8; icode in { IRET, IPOPQ } : 8; # Other instructions don't need ALU ];
## Select input B to ALU word aluB = [ icode in { IRMMOVQ, IMRMOVQ, IOPQ, ICALL, IPUSHQ, IRET, IPOPQ,IIADDQ } : valB; icode in { IRRMOVQ, IIRMOVQ } : 0; # Other instructions don't need ALU ];
## Should the condition codes be updated? bool set_cc = icode in { IOPQ, IIADDQ};
#/* $begin seq-all-hcl */ #################################################################### # HCL Description of Control for Single Cycle Y86-64 Processor SEQ # # Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2010 # ####################################################################
## Your task is to implement the iaddq instruction ## The file contains a declaration of the icodes ## for iaddq (IIADDQ) ## Your job is to add the rest of the logic to make it work
#################################################################### # C Include's. Don't alter these #不要改变这些 # ####################################################################
#################################################################### # Declarations. Do not change/remove/delete any of these # ####################################################################
##### Symbolic represenations of Y86-64 function codes Y86-64函数代码的符号表示 ##### wordsig FNONE 'F_NONE' # Default function code
##### Symbolic representation of Y86-64 Registers referenced explicitly明确引用的Y86-64寄存器的符号表示 ##### wordsig RRSP 'REG_RSP' # Stack Pointer wordsig RNONE 'REG_NONE' # Special value indicating "no register"
##### ALU Functions referenced explicitly ALU函数显式引用 ##### wordsig ALUADD 'A_ADD' # ALU should add its arguments
##### Possible instruction status values 可能的指令状态值 ##### wordsig SAOK 'STAT_AOK' # Normal execution wordsig SADR 'STAT_ADR' # Invalid memory address wordsig SINS 'STAT_INS' # Invalid instruction wordsig SHLT 'STAT_HLT' # Halt instruction encountered
##### Signals that can be referenced by control logic控制逻辑可参考的信号 ####################
##### Fetch stage inputs ##### wordsig pc 'pc' # Program counter ##### Fetch stage computations 获取阶段计算 ##### wordsig imem_icode 'imem_icode' # icode field from instruction memory 来自指令存储器的icode字段 wordsig imem_ifun 'imem_ifun' # ifun field from instruction memory来自指令存储器的ifun字段 wordsig icode 'icode' # Instruction control code指令控制码 wordsig ifun 'ifun' # Instruction function指导作用 wordsig rA 'ra' # rA field from instruction指令中的rA字段 wordsig rB 'rb' # rB field from instruction wordsig valC 'valc' # Constant from instruction指令中常数 wordsig valP 'valp' # Address of following instruction boolsig imem_error 'imem_error' # Error signal from instruction memory boolsig instr_valid 'instr_valid' # Is fetched instruction valid?
##### Decode stage computations ##### wordsig valA 'vala' # Value from register A port wordsig valB 'valb' # Value from register B port
##### Execute stage computations ##### wordsig valE 'vale' # Value computed by ALU boolsig Cnd 'cond' # Branch test
##### Memory stage computations ##### wordsig valM 'valm' # Value read from memory boolsig dmem_error 'dmem_error' # Error signal from data memory
#################################################################### # Control Signal Definitions. 控制信号定义 # ####################################################################
## What register should be used as the A source?哪个寄存器应该用作A源 word srcA = [ icode in { IRRMOVQ, IRMMOVQ, IOPQ, IPUSHQ } : rA; icode in { IPOPQ, IRET } : RRSP; 1 : RNONE; # Don't need register ];
## What register should be used as the B source? word srcB = [ icode in { IOPQ, IRMMOVQ, IMRMOVQ,IIADDQ } : rB; icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP; 1 : RNONE; # Don't need register ];
## What register should be used as the E destination? word dstE = [ icode in { IRRMOVQ } && Cnd : rB; icode in { IIRMOVQ, IOPQ,IIADDQ} : rB; icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP; 1 : RNONE; # Don't write any register ];
## What register should be used as the M destination? word dstM = [ icode in { IMRMOVQ, IPOPQ } : rA; 1 : RNONE; # Don't write any register ];
## Select input A to ALU word aluA = [ icode in { IRRMOVQ, IOPQ } : valA; icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ,IIADDQ } : valC; icode in { ICALL, IPUSHQ } : -8; icode in { IRET, IPOPQ } : 8; # Other instructions don't need ALU ];
## Select input B to ALU word aluB = [ icode in { IRMMOVQ, IMRMOVQ, IOPQ, ICALL, IPUSHQ, IRET, IPOPQ,IIADDQ } : valB; icode in { IRRMOVQ, IIRMOVQ } : 0; # Other instructions don't need ALU ];
## Set the ALU function word alufun = [ icode == IOPQ : ifun; 1 : ALUADD; ];
## Should the condition codes be updated? bool set_cc = icode in { IOPQ, IIADDQ};
################ Program Counter Update ############################
## What address should instruction be fetched at
word new_pc = [ # Call. Use instruction constant icode == ICALL : valC; # Taken branch. Use instruction constant icode == IJXX && Cnd : valC; # Completion of RET instruction. Use value from stack icode == IRET : valM; # Default: Use incremented PC 1 : valP; ]; #/* $end seq-all-hcl */