CSAPP第四章家庭作业参考答案

(CSAPP第三版系列)导航篇传送门


4.46

A.  这段代码序列没有正确描述指令popq %rsp的行为。该段代码序列使%rsp的值为(%rsp)+8,而指令popq%rsp执行后,%rsp的值应为(%rsp)。

B.  改写代码序列:

addq $8 , %rsp

movq-8(%rsp) , REG


4.48

冒泡排序函数的测试和交换(6-11行)代码:

if(data[i+1] < data[i]){
	/*Swap adjacent elements*/
	long t = data[i+1];
	data[i+1] = data[i];
	data[i] = t;
}
对应的Y86-64代码修改为条件转移,代码如下:

mrmovq  (%rdx), %r8
rrmovq  %rdx, %rsi
addq    %r10, %rsi
mrmovq  (%rsi), %rcx
rrmovq  %rcx, %r10
subq    %r8, %r10
rrmovq  %rcx, %r10
cmovl   %r8, %r10
rmmovq  %r10, (%rsi)
rrmovq  %r8, %r10
cmovl   %rcx, %r10
rmmovq  %r10, (%rdx)


4.50

Y86-64代码如下:

# Execution begins at address 0 
    .pos 0
    irmovq stack, %rsp      # Set up stack pointer
    call main       # Execute main program
    halt            # Terminate program 
# Array of 8 elements
    .align 8
vals:   
    .quad 0x000000000000
    .quad 0x000000000000
    .quad 0x000000000000
    .quad 0x000000000000
    .quad 0x000000000000
    .quad 0x000000000000
    .quad 0x000000000000
    .quad 0x000000000000

jump_table:
    .quad L1
    .quad L4
    .quad L2
    .quad L3
    .quad L4
    .quad L2

main:   
    irmovq  vals, %r12

    irmovq  $-1,%rdi
    call switchv        
    rmmovq  %rax, (%r12)

    irmovq  $0,%rdi
    call switchv        
    rmmovq  %rax, 0x8(%r12)

    irmovq  $1,%rdi
    call switchv        
    rmmovq  %rax, 0x10(%r12)

    irmovq  $2,%rdi
    call switchv        
    rmmovq  %rax, 0x18(%r12)

    irmovq  $3,%rdi
    call switchv       
    rmmovq  %rax, 0x20(%r12)

    irmovq  $4,%rdi
    call switchv        
    rmmovq  %rax, 0x28(%r12)

    irmovq  $5,%rdi
    call switchv        
    rmmovq  %rax, 0x30(%r12)

    irmovq  $6,%rdi
    call switchv        
    rmmovq  %rax, 0x38(%r12)

    ret

# long switchv(long idx)
# idx in %rdi
switchv:
    rrmovq %rdi, %r8
    irmovq $5, %r9
    subq %r9, %r8
    jg L4
    andq %rdi, %rdi
    jl L4
    irmovq jump_table, %r8
    irmovq $8, %r9
    irmovq $1, %r10
loop:
    subq %r10, %rdi
    jl endloop
    addq %r9, %r8
    jmp loop
endloop:
    mrmovq (%r8), %r8
    pushq %r8
    ret 

L1:             
    irmovq 0xaaa, %rax
    ret
L2:             
    irmovq 0xbbb, %rax
    ret
L3:
    irmovq 0xccc, %rax
    ret
L4:
    irmovq 0xddd, %rax  #default
    ret

# Stack starts here and grows to lower addresses
    .pos 0x300                          #栈开始地址不能太小
stack:
测试结果截图:



4.52

设计思想:

分析seq-full.hcl,需要对Instr_valid, need_regids, need_valC, srcB, dstE, aluA, aluB进行修改。

bool Instr_valid = icode in{…};  大括号中所列指令需加上IIADDQ

bool need_regids = icode in{…};  大括号中所列指令需加上IIADDQ

bool need_valC = icode in{…};  大括号中所列指令需加上IIADDQ

word srcB = [

icode in {…} : rB;  大括号中所列指令需加上IIADDQ

];

word dstE = [

    …

icode in {…} : rB;  大括号中所列指令需加上IIADDQ

];

word aluA = [

    …

icode in {… } : valC;  大括号中所列指令需加上IIADDQ

];

word aluB = [

   icode in { … } : valB;  大括号中所列指令需加上IIADDQ

    …

];

添加IIADDQ指令后seq-full.hcl文件:

#/* $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                               #
####################################################################

quote '#include <stdio.h>'
quote '#include "isa.h"'
quote '#include "sim.h"'
quote 'int sim_main(int argc, char *argv[]);'
quote 'word_t gen_pc(){return 0;}'
quote 'int main(int argc, char *argv[])'
quote '  {plusmode=0;return sim_main(argc,argv);}'

####################################################################
#    Declarations.  Do not change/remove/delete any of these       #
####################################################################

##### Symbolic representation of Y86-64 Instruction Codes #############
wordsig INOP    'I_NOP'
wordsig IHALT   'I_HALT'
wordsig IRRMOVQ 'I_RRMOVQ'
wordsig IIRMOVQ 'I_IRMOVQ'
wordsig IRMMOVQ 'I_RMMOVQ'
wordsig IMRMOVQ 'I_MRMOVQ'
wordsig IOPQ    'I_ALU'
wordsig IJXX    'I_JMP'
wordsig ICALL   'I_CALL'
wordsig IRET    'I_RET'
wordsig IPUSHQ  'I_PUSHQ'
wordsig IPOPQ   'I_POPQ'
# Instruction code for iaddq instruction
wordsig IIADDQ  'I_IADDQ'

##### Symbolic represenations of Y86-64 function codes                  #####
wordsig FNONE    'F_NONE'        # Default function code

##### Symbolic representation of Y86-64 Registers referenced explicitly #####
wordsig RRSP     'REG_RSP'      # Stack Pointer
wordsig RNONE    'REG_NONE'     # Special value indicating "no register"

##### ALU Functions referenced explicitly                            #####
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
wordsig imem_ifun  'imem_ifun'      # ifun field from instruction memory
wordsig icode     'icode'       # Instruction control code
wordsig ifun      'ifun'        # Instruction function
wordsig rA    'ra'          # rA field from instruction
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.                                   #
####################################################################

################ Fetch Stage     ###################################

# Determine instruction code
word icode = [
    imem_error: INOP;
    1: imem_icode;      # Default: get from instruction memory
];

# Determine instruction function
word ifun = [
    imem_error: FNONE;
    1: imem_ifun;       # Default: get from instruction memory
];

bool instr_valid = icode in 
    { INOP, IHALT, IRRMOVQ, IIRMOVQ, IIADDQ, IRMMOVQ, IMRMOVQ,
           IOPQ, IJXX, ICALL, IRET, IPUSHQ, IPOPQ };

# Does fetched instruction require a regid byte?
bool need_regids =
    icode in { IRRMOVQ, IOPQ, IPUSHQ, IPOPQ, 
             IIRMOVQ, IIADDQ, IRMMOVQ, IMRMOVQ };

# Does fetched instruction require a constant word?
bool need_valC =
    icode in { IIRMOVQ, IIADDQ, IRMMOVQ, IMRMOVQ, IJXX, ICALL };

################ Decode Stage    ###################################

## What register should be used as the A source?
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
];

################ Execute Stage   ###################################

## 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 };

################ Memory Stage    ###################################

## Set read control signal
bool mem_read = icode in { IMRMOVQ, IPOPQ, IRET };

## Set write control signal
bool mem_write = icode in { IRMMOVQ, IPUSHQ, ICALL };

## Select memory address
word mem_addr = [
    icode in { IRMMOVQ, IPUSHQ, ICALL, IMRMOVQ } : valE;
    icode in { IPOPQ, IRET } : valA;
    # Other instructions don't need address
];

## Select memory input data
word mem_data = [
    # Value from register
    icode in { IRMMOVQ, IPUSHQ } : valA;
    # Return PC
    icode == ICALL : valP;
    # Default: Don't write anything
];

## Determine instruction status
word Stat = [
    imem_error || dmem_error : SADR;
    !instr_valid: SINS;
    icode == IHALT : SHLT;
    1 : SAOK;
];

################ 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 */
模拟器测试结果截图(ISA Check Succeeds):



4.54

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值