• 计算机组成原理之指令


    发现更多的计算机知识,欢迎访问xiaocr的个人网站

    引言

    关于riscv操作数

    32个寄存器 | X0~X31|快速定位数据。在riscv中,只对寄存器中的数据执行算术运算

    2^61个存储字 | 只能被数据传输指令访问。riscv体系采用的是字节寻址。

    一个寄存器是8bytes,64位(double word)

    每次取的最小单位是一个byte

    注意:当函数参数大于8个的时候,会占用内存。本来是都在寄存器的

    riscv汇编语言

    程序一定是加载到内存中执行的。

    (如图)
    file

    计算机硬件的操作

    riscv体系中,寄存器大小64位,成组的64位频繁,被命名为双字。32位组成字。

    存储器操作数

    处理器只能在寄存器中保留少量数据,但内存可以存储大量数据。因此,数据结构(数组和结构体)保存在内存中。

    riscv是小端字节序的。比如说0x12345678。存储是高位地址是12.最低位存储的是78。

    网络字节序统一用的是大端序列。

    数据传输指令:在内存和寄存器之间传输数据的命令

    载入指令:将数据从内存复制到寄存器的数据传输命令

    例题:将 A [12] = h + A[8]转换为汇编代码。A的基址存储在X22,h存储在X9

    代码为:

    ld X9 , 64(X22) //Temporary reg X9 gets A[8]
    add X9 , X21 ,X9 //Temporary reg X9 gets A[8] + h
    sd X9, 96(X22) //stores h + A[8] back into A[12]

    常数或立即数操作数

    将常数4加到寄存器X22的两种方式:

    ld X9 , AddrConstant4(x3)      //X9 = constant4
    add x22 , x22 ,x9              //x22 = x22 +4
    //第二种
    addi x22, x22, 4
    
    • 1
    • 2
    • 3
    • 4

    第二种的addi指令可以避免加载指令,速度更加快。在许多体系中,字的起始地址必须是4的倍数,双字是8的倍数。

    计算机中的指令表示

    按照“简单源于规整的设计原则,Rsicv指令都是32位长。四位的对齐效率很高!

    Riscv字段

    opcode(操作码):指令的基本操作,这个是它的惯用名称

    rd :目的操作数寄存器,用来存档操作结果

    funct3 :一个另外的操作码字段

    rs1 :第一个源操作数寄存器

    rs2 :第二个源操作数寄存器

    funct7 :一个另外的操作码字段

    R型

    用于寄存器,减少访问内存的开销
    file

    funct7与funct3是用来细化解析的

    I型

    用于常数的算术指令
    file

    S型

    用于存储访问,将寄存器中的数据写入内存
    file

    汇编语言到机器语言

    例:A[30] = h + A[30] + 1;(A的基址在x10,h存放于X21)

    ld x9 , 240(x10)     //Temporary reg x9 gets A[30]
    add x9, x9 ,x21      //Temporary reg x9 gets h + A[30]
    addi x9, x9 ,1       //Temporary reg x9 gets h + A[30] + 1
    sd x9, 240(x10)       //store h + A[30] + 1 back into A[30]
    
    • 1
    • 2
    • 3
    • 4

    file

    关于指令的判断

    file

    逻辑操作

    file

    移位指令使用I格式,由于移位不会大于63,immediate字段使用低6位就可以。
    file
    funct6用来当做操作码字段。

    用于决策的指令

    例:if(i ==j) f = g + h; else f = g - h;

    汇编:

    bne (branch not equal)x22, x23, Else
    add x19, x20, x21
    beq x0, x0,Exit(遇到此指令必定跳过)
    Else : sub x19, x20, x21
    Exit
    
    • 1
    • 2
    • 3
    • 4
    • 5

    循环

    例: while(save[i]) == k) i+=1;

    loop: sli x10, x22 ,3     //Temp reg x10 = i * 8
    add x10 ,x10, x25         //x10 = address of save[i]
    ld x9, 0(x10)             //Temp reg x9 = save[i]
    bne x9 ,x24 ,Exit
    addo x22 ,x22, 1
    beq x0, x0,loop
    Exit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    计算机硬件对过程的支撑

    在执行程序过程时候,必须遵循六个步骤

    将参数放到可以访问的位置

    将控制转交给过程

    获取所需的存储资源

    将结果放在调用程序可以访问到的位置

    将控制返回到初始点,因为过程可以从程序的多个点调用

    Rsicv软件在为过程分配寄存器的时候遵循原则:

    x10~x17:八个参数寄存器,用于传递参数或返回值

    x1:一个返回地址的寄存器,用于返回到起始点

    除了将这些寄存器分配之外,Riscv编程语言还包含一个仅用于过程的指令:跳转-链接指令。

    jal x1,ProcedureAddress //jump to
    ProcedureAddress and write return address to x1
    上述代码中x1中这个链接称为返回地址。返回地址是必须要的,因为同一过程可能在程序的不同部分被调用。
    为了支持这种情况下面的过程返回,使用间接跳转jalr x0, (x1)

    jalr x0, (x1) 是一种 RISC-V 指令,用于无条件跳转到 x1 寄存器中存储的地址,并将下一条指令的地址存储在 x0 寄存器中。这是一种间接跳转,因为它不是直接跳转到一个特定的地址,而是跳转到一个存储在寄存器中的地址。这个指令的机器码是 0x00008067。

    使用更多的寄存器

    假如对一个过程,要使用超过8个参数寄存器。必须要采用寄存器换出到存储器当中

    换出寄存器的理想数据结构一种后进先出的stack)队列。栈需要一个指向栈中最新分配地址的指针,以指示下一个过程应该放置换出寄存器的位置或寄存器旧值的存放位置。

    在RISC-V中,栈指针(stack pointer)是寄存器x2,也称为Sp。栈指针按照每个被保存或恢复的寄存器按双字进行调整。栈应用非常广泛,因而传送数据到栈或从栈传输数据都具有专业术语:将数据放入栈中称为压栈,从栈中移除数据称为弹栈

    栈例子:

    file
    file
    图示结构:
    file

    寄存器用途

    • x0: the constant value 0

    • x1: return address

    • x2: stack pointer

    • x3: global pointer

    • x4: thread pointer

    • x5 - x7, x28 - x31: temporaries

    • x8: frame pointer

    • x9,x18 - x27: saved registers

    • x10 - x11: function arguments/results

    • x12 - x17: function arguments

    递归例子

    file
    file

    内存模型

    file

    大立即数编址与寻址

    RISC-V指令系统包括指令 load upper immediate(取立即数高位,lui),用于将20位常数加载到寄存器的第31位到第 12位。将第31位的值复制填充到最左边 32位,最右边的 12 位用0填充。例如,这条指令允许使用两条指令创建 32位常量。lui 使用新的指令格U型,因为其他格式不能支持如此大的常量。

    分支寻址

    file
    SB格式(可表示-4096 - 4096的分支地址)

    寻址模式的总结

    file
    在PC寻址的时候:Targetaddress = PC + immediate * 2

    翻译并启动程序

    过程:

    C程序–>预处理(#开头的全部处理掉)–>编译(变为汇编语言) -->汇编(变为机器语言)–>链接(目标文件链接为整体)

    图示:
    file
    动态链接器:

    动态链接器是操作系统的一部分,用于在执行可执行文件时(在“运行时”),将可执行文件所需的共享库从持久存储复制到 RAM 中,并填充跳转表和重定位指针。具体的操作系统和可执行文件格式决定了动态链接器的功能和实现方式。动态链接器通常被称为在编译可执行文件时执行的过程,而动态链接器是操作系统的一个特殊部分,它将外部共享库加载到正在运行的进程中,然后动态地将这些共享库绑定到正在运行的进程中。这种方法也称为动态链接或后期链接。1

    但是java不是编译成目标计算机的汇编语言,而是首先编译成易于解释的指令(Java字节码)
    file

    感谢您阅读本文,希望对您有帮助。

    本文作者:Cr不是铬 QQ:2195821921,欢迎交流讨论。

    转载请注明出处:Chapter2 指令:计算机的语言

    本文由博客一文多发平台 OpenWrite 发布!

  • 相关阅读:
    EasyRecovery2024破解版激活码
    springcloud springboot nacos版本对应
    uniapp后台播放音频功能制作
    中国钨粉行业市场研究与投资预测报告(2022版)
    这篇文章告诉你时光穿梭机特效从年轻变老制作软件
    RK3568 安卓12 EC20模块NOCONN没有ip的问题(已解决)
    基于Matlab求解高教社杯全国大学生数学建模竞赛(cumcm2014B题)-创意平板折叠桌(附上源码+数据+题目)
    OWASP TOP 10解析:构建坚不可摧的Web应用安全防线
    针对支付宝-当面付实现的个人支付
    【Python入门指北】 发邮件与正则表达式
  • 原文地址:https://blog.csdn.net/m0_73421035/article/details/134321294