Risc-V学习日记06

Risc-V学习日记06
Day12
算术运算指令(Arithmetic Instructions)
ADD
    语法:ADD RD,RS1,RS2
    例子:add x5,x6,x7  x5=x6+x7
        opcode(7):01-100|11(OP)//查表page130
        "R-type"
            rs2,rs1,rd[用于存放寄存器参数]
            rd(register destination)存放结果
            rs(register source)源数据
            一个寄存器占5个bit
        funct3:000//查表page130
        funct7:0000000//查表page130
        0000000|RS2|RS1|000|RD|01-100|11
        7+6=13
            0x007302B3转化为二进制
            0000-0000-0111-0011-0000-0010-1011-0011
                000000000111-00110-000-00101-0110011    
                    OP:
                    01-100-11
                    00000000011100110000-00101   
                        RD:
                            00110
                                00000000011100110-000
                                    funct3
                                        000
                                            000000000111-00110
                                                rs1
                                                    01100
                                                        0000000-00111
                                                            rs2
                                                                00111
                                                                    funct7:0000000
SUB减法
    语法:SUB RD,RS1,RS2
        例子:sub x5,x6,x7  x5=x6-x7
rule.mk
    debug:
        @echo "Press Ctrl-C and then input 'quit' to exit GDB and QEMU"
	    @echo "-------------------------------------------------------"
	    @${QEMU} ${QFLAGS} -kernel ${EXEC}.elf -s -S &
            QEMU=qemu-system-riscv32//模拟器模拟riscv32
            QFLAGS=-nographic -smp 1 -machine virt -bios none
                nographic:不起图形界面
                smp:用一个hart
                virt:使用的设备类型为virt 
            -s:使用远程调试模式,运行了一个gdbserver与gdb通信
            -S:使程序中断
            &:把qemu放在后台
	    @${GDB} ${EXEC}.elf -q -x ${GDBINIT}
        -q:清理
        -x:启动脚本{GDBINIT}
            {GDBINIT}
                避免每次手动去链接服务器
                
exercise:{{
    	.text			# Define beginning of text section
	    .global	_start		# Define entry _start

_start:
	li x6, 1		# x6 = 1
	li x7, 2		# x7 = 2
	add x5, x6, x7		# x5 = x6 + x7

stop:
	j stop			# Infinite loop to stop execution
#死循环
	.end			# End of file
}
不能直接从windows拖文件进虚拟机会搞乱makefile文件格式
git clone https://gitee.com/unicornx/riscv-operating-system-mooc.git

make
make hex
    13 03 10 00|93 03 20 00|b3 02 73 00|6f 00 00 00
    b3 02 73 00为add——————>0x007302B3 //小端序

make code
//makerun Ctrl-a 再按x强制停止qemu
//makedebug Ctrl-c 输入quit  

make debug
    si单步执行 (step Instructions)
    回车自动执行上步指令
}

无符号数,有符号数:
    有符号数在计算机中的表示:二进制补码(twoscomplement)
        例如,十进制的-3用8位二进制补码表示是:
            绝对值的二进制表示为3:0000 0011
            按位取反:1111 1100
            加1:1111 1101
    符号扩展(Sign extension)v.s. 零扩展(Zeroextension)
        符号扩展
            例如,考虑一个8位的有符号整数:11010110。如果我们要将其符号扩展为16位,那么,由于最高位是1(表示负数),在高位填充1,得到:1111111111010110
        零扩展
            例如,考虑一个8位的无符号整数:01010110。如果我们要将其零扩展为16位,那么在高位填充零,得到:0000000001010110

exercise_5_1
    0x00001000 in ?? ()
    => 0x00001000:	97 02 00 00	auipc	t0,0x0
    1: /z $x5 = 0x00000000
    2: /z $x6 = 0x00000000
    3: /z $x7 = 0x00000000
        97 02 00 00     0x00-00-02-97             
        0x0 -> 0000
        0x0 -> 0000
        0x0 -> 0000
        0x2 -> 0010
        0x9 -> 1001
        0x7 -> 0111
            0000-0000-0000-0000-0000-0010-1001-0111
            "U-type"
            0000000000000000000000101-0010111
            001-01-11
            OP:001-01-11[STORE-FP]
            imm(立即数):0000000000000000000000101
            AUIPC
                qemu默认起始地址为0x80000000
                Add Upper Immediate to PC
                AUIPC指令用于将一个符号扩展的立即数与PC(程序计数器)的上位部分相加,然后将结果存储到目标寄存器中。它主要用于计算全局地址
                    1.将PC(程序计数器)的上位部分(前20位)拷贝到目标寄存器的位置。
                    2.将符号扩展的立即数(左移12位)与上一步得到的值相加。
                    3.将相加的结果存储到目标寄存器中。
                        AUIPC指令在处理全局地址时非常有用,因为它可以将一个相对较大的立即数与当前PC的上位部分相加,从而实现较大范围的跳转和地址计算。
                        此时x5 = 0x80000000??目前还未解释
    Breakpoint 1, _start () at test.s:12
    12		li x6, -1		# x6 = -1
    => 0x80000000 <_start+0>:	13 03 f0 ff	li	t1,-1
    1: /z $x5 = 0x80000000 #(由于AUIPC指令加载了PC + 0x1000的值,因此初始PC为0x80000000。)
    2: /z $x6 = 0x00000000
    3: /z $x7 = 0x00000000
        13 03 f0 ff     0xff-f0-03-13
        0 -> 0000
        1 -> 0001
        3 -> 0011
        f -> 1111
            1111-1111-1111-0000-0000-0011-0001-0011
            OP:0010011
            rd=0011-0
            1111-1111-1111-0000-0-000
            funct3=000
                所以为ADDI
            rs1=00000
            111111111111-00000-000-00110-0010011
            ADDI它是"Add Immediate"的缩写。ADDI指令用于将一个立即数与一个源寄存器的值相加,并将结果存储到目标寄存器中
                ADDI指令的执行过程如下:
                    1.从rs1寄存器中取出源操作数的值。00000
                    2.将立即数imm与源操作数相加。111111111111+00000=111111111111
                        首先,查看二进制数"111111111111"的最高位,它是1,所以是一个负数。
                        取反:将"111111111111"中的0变1,1变0得到"000000000000"。
                        加1:在取反的结果上加1,得到"000000000001"
                    3.将相加的结果存储到目标寄存器rd中。rd=-1
    (gdb) si
    13		li x7, -2		# x7 = -2
    => 0x80000004 <_start+4>:	93 03 e0 ff	li	t2,-2
    1: /z $x5 = 0x80000000
    2: /z $x6 = 0xffffffff
    3: /z $x7 = 0x00000000
    
    (gdb) 
    14		sub x5, x6, x7		# x5 = x6 - x7
    => 0x80000008 <_start+8>:	b3 02 73 40	sub	t0,t1,t2
    1: /z $x5 = 0x80000000
    2: /z $x6 = 0xffffffff
    3: /z $x7 = 0xfffffffe
    (gdb) 
    stop () at test.s:17
    17		j stop			# Infinite loop to stop execution
    => 0x8000000c <stop+0>:	6f 00 00 00	j	0x8000000c <stop>
    1: /z $x5 = 0x00000001
    2: /z $x6 = 0xffffffff
    3: /z $x7 = 0xfffffffe
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值