西西河

主题:MIPS体系结构学习笔记(一) -- 镭射

共:💬9 🌺12
全看树展主题 · 分页首页 上页
/ 1
下页 末页
家园 MIPS体系结构学习笔记(一)

本人订购的《MIPS体系结构与编程》到货了,刚刚读完第二章《MIPS结构体系概述》,记录若干心得如下:

和我以前学过的X86结构体系相比,MIPS结构体系给我的印象就是两个字:简洁。X86系统的寄存器有14个,划分为四类:通用寄存器,指令指针寄存器,标志寄存器,段寄存器。相比之下,MIPS的寄存器比X86要多,有35个,但其中有32个(r0~31)是通用寄存器,两个(HI,LO)是特殊功能寄存器(用于存储整数乘除和乘/累加操作的结果),还有一个是特殊功能程序计数器,由特定指令直接操作,对程序员不可见。也就是说,程序员面对的寄存器只有两种:通用寄存器和特殊功能寄存器。

在32个通用寄存器中,第一个寄存器r0被硬件连接成低位,也就是说,它的值是恒定的,总是0。因此这个寄存器一般被用于结果不需要保存的操作,以及作为需要0值时的来源。最后一个寄存器r31在没有特殊说明的情况下,是用于存放子函数的返回地址。同时,它也可以作为普通的寄存器使用。除了r0和r31,其他寄存器都是作为一般的寄存器使用。也就是说,MIPS有31个通用寄存器可以使用,这比X86(8个)要多的多。

虽然有这么多寄存器,但在实际使用中,这些寄存器的用法都遵从一些约定俗成的规定。比如r31虽然可以作为通用寄存器使用,但它一般是专用于存放子函数的返回地址,而不用做其他用途。这样可以提高程序的可读性。

一个问题:书上介绍,每个寄存器除了名字(r0,r1等)还有编程时的命名,比如r0叫zero,r1叫at,r31叫ra,等等。这是不是意味着MIPS的汇编语言中使用的是后一套名字?

家园 See MIPS Run Linux,有电子版。
家园 一般,不怎么用汇编写的

反汇编出来的,都是后一套名字。

比如

jr ra,其实就是jr $31

家园 MIPS体系结构学习笔记(二)

作为一种RISC指令集,MIPS指令集的所有指令的长度都相同,都是32位。按功能可划分为五类:加载和存储指令、算术指令、跳转和分支指令、杂类指令和协处理器指令。

1、加载/存储指令

因为CPU与外部存储器打交道的指令执行时间远大于在寄存器内操作的指令执行时间,因此RISC型CPU都采用加载/存储结构,只有加载和存储指令才能对存储器进行操作。MIPS处理器也是如此。加载和存储指令主要完成以下操作:

(1)传输可变大小的字段,比如字节、半字和字。

(2)访问有/无符号整型数据。

(3)访问未对齐的字段。

(4)选择寻址模式。

(5)原子内存刷新,即读取-修改-写回操作序列。

MIPS加载和存储指令的命名规则如下:

(1)首字母L表示“加载”,S表示“存储”。

(2)首字母U表示“无符号”,其余默认为有符号。

(3)尾字母R表示“右”,L表示“左”。

(4)字母B表示“字节”,H表示“半字”,W表示“字”。

比如,LWL的功能是加载字头,LWR的功能是加载字尾,SWL的功能是存储字头,SWR的功能是存储字尾。

根据用途的不同,还可以将加载和存储指令分为对齐加载和存储指令、非对齐加载和存储指令以及原子刷新加载和存储指令等。

家园 对齐加载指令和存储指令

对齐加载和存储指令在MIPS CPU寄存器和对齐的内存区域之间传送字节、字、双字数据。

LH(load halfword)

该指令将有效地址确定的内存中的半字加载到目标寄存器两个字节的最低有效位LSB(least significant bit)。加载的半字被认为是一个有符号的值。如果有效地址非偶,会产生一个地址错误异常。

指令格式:LH rt ,offset(base)

指令描述:rt<- memory[base+offset]

16位有符号地址偏移量offset与通用基址寄存器base相加形成有效地址,此对齐的有效地址确定内存中的一个16位的半字。LH指令将该半字取出,经过符号扩展后,赋值给通用寄存器rt。

约束:有效地址必须自然对齐。如果地址中LSB非零,就会产生一个地址错误异常。

实例:LH t0,10(t2)

家园 非对齐加载指令和存储指令

一般说来,硬件访问内存时传递的是4或8个字节的对齐数据,这样与硬件的设计相一致,提高了访问效率。非对齐字的存储可以让对齐区域中的某些字节不被改变,也可以让RMW序列对字或双字进行操作。通过使用非对齐加载和存储指令,需要用两条指令来加载和存储内存中未对齐的字或双字。一条加载指令从内存中一个对齐的字中读其左端或右端某些字节(放在寄存器的左或右边),另一条加载指令从内存中刚读取字的相邻位置读取右端或左端字节,然后将其合并为目标寄存器中正确的字。存储指令将一个对齐的字中左端或右端字节(源自寄存器的左或右边),存储至不对齐的内存地址。

家园 LWL(load word left)

该指令从未对齐的内存地址(有效地址)中加载一个字的最高有效部分,作为一个有符号的值,放入目标寄存器中。

指令格式: LWL rt,offset(base)

指令描述: rt<-rt MERGE memory[base+offset]

16位的有符号地址偏移量offset与通用基址寄存器base相加以形成有效地址,此地址是内存中起始于任意字节边界的4个连续字节(组成一个字W)的最高有效字节地址。W中的1到4个最高有效字节处于包含此有效地址的对齐字中,这部分字节加载到目标寄存器rt的最高有效位置(左边),rt中剩下的最低有效位置(右边)保持不变。

LWR的有效位定义与LWL相反。在LWR $24,5($0)指令中,偏移量5与基址寄存器相加形成有效地址。从位置5开始向前连续4个字节形成一个非对齐字(位置5对应LSB)。对齐字(包含4~7字节)包含了非对齐字的2个LSB字节。LWR加载这两个字节到目标寄存器的右半部分(最低的2个字节),目标字左半部分不变。

LWL/LWR指令加载的字节数取决于非对齐字相对于对齐字的偏移量,即与有效地址的低两位(vAddr1.0)及处理器的当前字节顺序(大尾端或小尾端)有关。

家园 x86是16个寄存器, 不是14个
家园 这几条用得不多

只是在处理非对齐加载/存储异常的handler里面用得着。

全看树展主题 · 分页首页 上页
/ 1
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河