Lecture 2 Instructions: Language of the Machine

Outline

  • Introduction
  • Operations of the computer hardware (计算机硬件的操作)
  • Operands of the computer hardware(计算机硬件的操作数)
  • Signed and unsigned numbers (有符号和无符号数) 太简单跳过了
  • Representing instructions in the computer(计算机中指令的表示)
  • Logical operations(逻辑操作)
  • Instructions for making decision(决策指令)
  • Supporting procedures in computer hardware(计算机对过程的支持) (函数)
  • Instruction addressing (指令的寻址)

Operation

design principle 1 Simplicity favors regularity
规范化让操作更简单
简单可以保证低消耗和高性能

32 bits = 1 word
64 bits = double word

Operand

  1. x0-x31 64bit general registers. design principle 2 Smaller is faster 但是2的倍数永远最优
    1. image-20220609163145328
  2. 对内存的操作只能通过ld、sd两类指令完成
    内存比寄存器慢
    翻译器必须尽量使用寄存器
  3. Little Endian: 小端规则,超过一个word的内容如何排序:小字节放在小的地址(前面),高字节放后面(0x12345678:内存从左至右78 56 34 12)
    least significant byte at least address of a word 最低位放在小端
    MIPS ARM Alpha SPARC使用大端规则
  4. Risc-V不需要内存中的word内存对齐(memory alignment)
  5. RISCV中的立即数
  6. RISCV R-Format Instruction
function(7b) RS2(5b) RS1(5b) function(3b) DR(5b) opcode(7b)
0000000 00000 00000 000 00000 0000000

design principle 3 Good design demands good compromises
不同的格式会增大decoding的难度,但是要允许这类情况
尽量保持指令格式相同

  1. RISCV S-Format Instruction
imm[11:5] RS2 RS1 function imm[4:0] opcode(7b)
7b 5b 5b 3b 5b 0000000

design principle 3 Good design demands good compromises

  1. 现阶段计算机两大principle
    指令被当作数字
    程序被当作数字存在内存中——冯诺依曼架构

  2. 指令集结构的几种类型

  3. R-type 三个R

  4. I-type 两个R一个立即数

  5. S-type

  6. SB-type

  7. UJ-type

  8. U-type

image-20220609162926890

Logical Operations

  1. Instructions for bitwise manipulation
Operation RISCV
Shift left logical slli
Shift right srli
Bit-by-bit AND and, andi
Bit-by-bit OR or, ori
Bit-by-bit XOR/NOT xor, xori
  1. RISC-V assembly language of logical and shift

  2. logical:
    and/or/xor/andi/ori/xori dr, sr1, sr2

  3. shift:
    sll/srl/sra/slli dr, sr1, sr2

Instructions for making decisions

  1. Branch instructions

    1. beq r1, r2, Location 相等就跳转到 Location
    2. bne r1, r2, Location 不等就跳转到 Location
  2. An Example of if else then clause

    1. bne r1,r2. ELSE
    2. things to do if
    3. beq x0,x0, EXIT
    4. ELSE: else do
    5. EXIT: exit
  3. Supports LOOPS

    1. LOOP: ......
    2. add x22,x22,x23(x22++)
    3. bne x22,x21,LOOP
  4. Suport while

    1. 和loop类似。区别:开头一个exit的判断和跳转,loop末尾一个铁定的jump
  5. set on less than : slt

    1. slt x5, x19, x20 # set x5=1 if x19 < x20
  6. other conditional operation

    1. blt rs1,rs2,L1 #if(rs1<rs2)branch to instruction L1
    2. bge rs1,rs2,L1 # if(rs1>=rs2)branch to instruction L1
    3. bltu bgeu: Unsigned Comparison
  7. Hold out Case/Switch:
    很诡异,只有case0123这样才会支持
    jalr r1,imm(r2) 跳到r2加上偏移量,然后将下一句话的地址存到r1

  8. Important conception–Basic Blocks

    1. 除了结尾之处,没有内置分支
    2. 除了开始之处,没有分支标签
  9. Supporting Procedures in Computer Hardware 如何支持函数调用?
    传入参数到一个函数可以访问的地方 (argument)
    把控制权交给进程(jump到那个位置)
    得到寄存器的储存资源(原来的值暂存)
    做想做的事情
    把算好的结果放到主函数能接触到的地方
    返回到原先的位置

  10. Procedure Call Instructions

  11. Caller使用 jal 指令
    jal指令: jump and link jal x1, ProcedureAddress
    把下一个指令的位置(要返回的位置)放到x1
    然后条到 ProcedureAddress的位置

  12. Callee使用 jalr 指令
    jalr指令:jump and link register jalr x0,0(x1)
    把下一条指令的位置放到x0(实际啥也没干)
    然后跳到x1+0的位置

  13. Using More Registers

    1. More Registers for procedure calling:

      1. a0 ~ a7(x10-x17): eight argument registers to pass parameters & return values
      2. ra/x1:one return address register to return to origin point
    2. Stack:

      1. ideal data structure for spilling registers
      2. Push, pop , Stack pointer ( sp )

      image-20220318213003046

  14. Pointer of stack
    $fp
    saved argument registers
    saved return address
    saved saved resisters
    Local variables
    $sp

  15. 内存中的映射:(地址从上往下由高到低)
    image-20220318214910358
    static data是全局变量
    Text是程序代码
    Dynamic data 是malloc开的heap
    stack是自动存储的栈

  16. Byte / Halfword / Word Operation

    1. 1 byte = 8 bits
    2. 1 Halfword = 2 Byte
    3. 1 Word = 4 Byte
    4. 1 Doubleword = 8 Byte
    5. the offset of the instruction is used by Byte
      1. lb,lh,lw,ld 这几个要sign extend to 64 bits
      2. lbu lhu lwu ldu 这几个要0 extend to 64 bits
# 我宣布我已经领略到汇编语言的真谛了
# 汇编语言最难处理的就是递归和函数调用
# 这里我给出一个递归/函数调用的公式化例子

# lw sw 的时候一个单位为4, ld sd 的时候为8
# 函数自己管理自己的内容,自己分配并恢复自己的空间
# 所有函数除了a类型t类型,其他寄存器都是公用的
addi sp,x0,1024
j GOGO
Fib:
addi sp,sp,-16 #1 进入函数,首先先分配内存
sw ra,12(sp) #2 其次存储返回地址和frame pointer
sw s0,8(sp)
addi s0,sp,16 #3 给frame pointer赋值,从-4开始一直到-16,其中-4-8保留
sw a0,-12(s0) # frame pointer的作用是一个函数内的变量偏移base

lw a0,-12(s0) #4 开始执行内容,这里的操作以memory为准,不以寄存器为准
beq a0,x0,RETA # 这里面的a0只是用来暂时存放num,不代表映射num
addi t0,x0,1 # t0不实际占用mem,只是临时存放
beq a0,t0,RETA

lw a0,-12(s0)
addi a0,a0,-1
jal ra,Fib
add a1,a0,x0
sw a1,-16(s0) # 记录中间过程作为临时变量
lw a0,-12(s0) # 恢复a0
addi a0,a0,-2
jal ra,Fib
lw a1,-16(s0)
add a0,a0,a1
sw a0,-12(s0) #5 算出的结果存入mem,为退出做准备
RETA:
lw a0,-12(s0) #6 从mem读出结果,准备退出
lw ra,12(sp) #7 恢复ra和s0,这里用的是sp做偏移地址,s0被弃用
lw s0,8(sp)
addi sp,sp,16 #8 释放内存
jr ra #9 跳回
GOGO:
addi a0,x0,6
jal ra,Fib

Addressing Method

  1. RISCV fot 32 bit Immediate and Address (Wide bit addressing)

    1. use instruction lui:lui s3,976(高20位放到s3里面)U format
    2. addi s3,s3, imm12低12位对s3加
  2. Branch Addressing

    1. SB\Uj format 在后面都补一个0,寻址能力*2
    2. (只有condition branch(SB)类型和unconditional jump(UJ)类型在后面加0,ldsd都不加)
  3. Jump Addressing

image-20220321110351490

Synchronization in Risc-V

  1. Use Lock and atomic operation:
    1. Load reserved: lr.d rd,(rs1)
    2. Store conditional: sc.d rd,(rs1),rs2