官术网_书友最值得收藏!

3.3 加載與存儲指令

和其他RISC體系結(jié)構(gòu)一樣,RISC-V體系結(jié)構(gòu)也基于加載和存儲的體系結(jié)構(gòu)設(shè)計(jì)理念。在這種體系結(jié)構(gòu)下,所有的數(shù)據(jù)處理都需要在通用寄存器中完成,而不能直接在內(nèi)存中完成。因此,要先把待處理數(shù)據(jù)從內(nèi)存加載到通用寄存器,然后進(jìn)行數(shù)據(jù)處理,最后把結(jié)果寫回內(nèi)存中。

1.加載指令

加載指令的格式如下。

l{d|w|h|b}{u} rd,  offset(rs1)

其中,相關(guān)選項(xiàng)的含義如下。

{d|w|h|b}:表示加載的數(shù)據(jù)寬度。加載指令如表3.1所示。

{u}:可選項(xiàng),表示加載的數(shù)據(jù)為無符號數(shù),即采用零擴(kuò)展方式。如果沒有這個(gè)選項(xiàng),則加載的數(shù)據(jù)為有符號數(shù),即采用符號擴(kuò)展方式。

rd:表示目標(biāo)寄存器。

rs1:表示源寄存器1。

(rs1):表示以rs1寄存器的值為基地址進(jìn)行尋址,簡稱rs1地址。

offset:表示以源寄存器的值為基地址的偏移量。offset是12位有符號數(shù),取值范圍為[?2048, 2047]。

表3.1 加載指令

上述加載指令的編碼如圖3.3所示,其中opcode字段都是一樣的,唯一不同的是funct3字段。

圖3.3 加載指令的編碼

【例3-2】 下面的代碼使用了加載指令。

1    li t0, 0x80000000
2
3    lb t1, (t0)
4    lb t1, 4(t0)
5    lbu t1, 4(t0)
6    lb t1, -4(t0)
7    ld t1, (t0)
8    ld t1, 16(t0)

第1行是一條偽指令,表示把立即數(shù)加載到t0寄存器中。

在第3行中,從以t0寄存器的值為基地址的內(nèi)存中加載1字節(jié)的數(shù)據(jù)到t1寄存器,并對這1字節(jié)的數(shù)據(jù)進(jìn)行符號擴(kuò)展。符號擴(kuò)展是計(jì)算機(jī)系統(tǒng)把小字節(jié)數(shù)據(jù)轉(zhuǎn)換成大字節(jié)數(shù)據(jù)的規(guī)則之一,它將符號位擴(kuò)展至所需要的位數(shù)。例如,一個(gè)8位的有符號數(shù)為0x8A,它的最高位(第7位)為1,因此在做符號擴(kuò)展的過程中,高字節(jié)部分需要填充為0xFF,如圖3.4所示,符號擴(kuò)展到64位的結(jié)果為0xFFFF FFFF FFFF FF8A。

圖3.4 符號擴(kuò)展

在第4行中,以t0寄存器的值為基地址加上4字節(jié)的偏移量為內(nèi)存地址(0x8000 0004),再從這個(gè)內(nèi)存地址中加載1字節(jié)的數(shù)據(jù)到t1寄存器中,并對該字節(jié)的數(shù)據(jù)進(jìn)行符號擴(kuò)展。

第5行中的指令與第4行中的指令基本類似,不同之處在于該字節(jié)的數(shù)據(jù)不會做符號擴(kuò)展,即按照無符號數(shù)處理,因此高字節(jié)部分填充為0,稱為零擴(kuò)展,如圖3.5所示。

圖3.5 零擴(kuò)展

在第6行中,以t0寄存器的值為基地址減去4字節(jié)的偏移量為內(nèi)存地址(0x7FFF FFFC),再從這個(gè)內(nèi)存地址中加載1字節(jié)的數(shù)據(jù)到t1寄存器中,并對該字節(jié)的數(shù)據(jù)進(jìn)行符號擴(kuò)展。

在第7行中,從以t0寄存器的值為基地址的內(nèi)存中加載8字節(jié)的數(shù)據(jù)到t1寄存器中。

在第8行中,以t0寄存器的值為基地址加上16字節(jié)的偏移量為內(nèi)存地址(0x8000 0010),再從這個(gè)內(nèi)存地址中加載8字節(jié)的數(shù)據(jù)到t1寄存器中。

【例3-3】 下面的代碼使用LUI加載立即數(shù)。

lui t0, 0x80200
lui t1, 0x40200

在第1行中,首先把0x80200左移12位得到0x8020 0000,然后進(jìn)行符號擴(kuò)展,最后結(jié)果為0xFFFF FFFF 8020 0000。

在第2行中,首先把0x40200左移12位得到0x4020 0000,然后進(jìn)行符號擴(kuò)展,因?yàn)樽罡呶粸?,所以最后結(jié)果為0x4020 0000。

【例3-4】 下面的代碼有錯誤。

lb a1, 2048(a0)
lb a1,-2049(a0)

上述指令的偏移量超過了取值范圍,匯編器會報(bào)錯。

AS   build_src/boot_s.o
src/boot.S: Assembler messages:
src/boot.S:6: Error: illegal operands 'lb a1,-2049(a0)'
src/boot.S:7: Error: illegal operands 'lb a1,2048(a0)'
make: *** [Makefile:28: build_src/boot_s.o] Error 1

2.存儲指令

存儲指令的格式如下。

s{d|w|h|b} rs2,  offset(rs1)

其中,相關(guān)選項(xiàng)的含義如下。

{d|w|h|b}:表示存儲的數(shù)據(jù)寬度。根據(jù)數(shù)據(jù)的位寬,存儲指令的分類如表3.2所示。

rs1:表示源寄存器1,用來表示基地址。

(rs1):表示以rs1寄存器的值為基地址進(jìn)行尋址,簡稱rs1地址

rs2:表示源寄存器2,用來表示源操作數(shù)。

offset:表示以源寄存器的值為基地址的偏移量。offset是12位有符號數(shù),取值范圍為[?2048, 2047]。

表3.2 存儲指令的分類

主站蜘蛛池模板: 汾西县| 邵阳市| 海南省| 南宫市| 溆浦县| 遂昌县| 安多县| 桐柏县| 万全县| 陆良县| 惠东县| 道真| 桃源县| 新巴尔虎左旗| 汾西县| 肥西县| 金湖县| 罗山县| 贵溪市| 安龙县| 蒙城县| 横峰县| 锡林浩特市| 乌鲁木齐县| 莱芜市| 安徽省| 布拖县| 宁都县| 满城县| 滦南县| 博爱县| 洛隆县| 安多县| 凤台县| 油尖旺区| 嘉鱼县| 乐昌市| 军事| 古浪县| 湛江市| 古浪县|