MIPS体系结构.docx
- 文档编号:30309263
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:70
- 大小:53.89KB
MIPS体系结构.docx
《MIPS体系结构.docx》由会员分享,可在线阅读,更多相关《MIPS体系结构.docx(70页珍藏版)》请在冰豆网上搜索。
MIPS体系结构
MIPSCPU体系结构概述http:
//www.xtrj.org/mips/
陈怀临
1。
序言
本文介绍MIPS体系结构,着重于其寄存器约定,MMU及存储管理,异常和中断处理等等。
通过本文,希望能提供一个基本的轮廓概念给对MIPSCPU及之上OS有兴趣的读者。
并能开始阅读更详细的归约(SPECIFICATION)资料。
MIPS是最早的,最成功的RISC(ReducedInstructionSetComputer)处理器之一,起源于StanfordUniv的电机系.其创始人JohnL.Hennessy在1984年在硅谷创立
了MIPSINC.公司()。
JohnL.Hennessy目前是StanfordUniv.的校长。
在此之前,他是Stanford电子工程学院的Dean。
CS专业的学生都知道两本著名的书:
“ComputerOrganizationandDesign:
TheHardware/SoftwareInterface”和
”ComputerArchitecture:
AQuantitativeApproach“。
其Co-author就是Hennessy.
MIPS的名字为“Microcomputerwithoutinterlockedpipelinestages"的缩写。
另外一个通常的非正式的说法是”Millionsofinstructionspersecond".
MIPS芯片在工业界目前用的比较多的是:
MIPSINC。
的R10000;QED(。
1996年从MIPSINC。
分(SPINOFF)出来的)的R5000,R7000等。
指令集
详细的资料请参阅MIPS归约。
一般而言,MIPS指令系统有:
MIPSI;MIPSII;MIPSIII和MIPSIV。
可想而知,指令系统是向后兼容的。
例如,基于MIPSII的代码可以在MIPIII和MIPSIV的处理器上跑一跑:
-)
下面是当我们用gcc时,如何指定指令和CPU的选项。
-mcpu=cputype
Assumethedefaultsforthemachinetypecputypewhenschedulinginstructions.Thechoicesforcputypeare`r2000',`r3000',`r4000',`r4400',`r4600',
and`r6000'.Whilepickingaspecificcputypewillschedulethingsappropriatelyforthatparticularchip,thecompilerwillnotgenerateanycodethatdoes
notmeetlevel1oftheMIPSISA(instructionsetarchitecture)withoutthe`-mips2'or`-mips3'switchesbeingused.
-mips1
Issueinstructionsfromlevel1oftheMIPSISA.Thisisthedefault.`r3000'isthedefaultcputypeatthisISAlevel.
-mips2
Issueinstructionsfromlevel2oftheMIPSISA(branchlikely,squarerootinstructions).`r6000'isthedefaultcputypeatthisISAlevel.
-mips3
Issueinstructionsfromlevel3oftheMIPSISA(64bitinstructions).`r4000'isthedefaultcputypeatthisISAlevel.ThisoptiondoesnotchangethesizesofanyoftheCdatatypes.
读者可能发现,对于大多数而言,我们应该是用MIPSIII或-mips3。
要提醒的是R5000和R10000也都是R4000的延伸产品。
下面是几点补充:
*MIPS指令是32位长,即使在64位的CPU上。
这对于局部跳转指令的理解很有帮助。
比如:
J(TARGET);JAL(TARGET)。
J和JAL的OPERCODE是6位,剩下的26为存放跳转偏移量。
由于任何一个指令都是32位(或4字节)对齐(ALIGN)的,所以J和JAL最大的伸缩空间是2^28=256M。
如果你的程序要作超过256M的跳转,你就必须用JALR或JR,通过一个GPR寄存器来存放你的跳转地址。
由于一个寄存器是32或64位的,你就没有任何限制了。
*MIPSCPU的SR(STATUSREGISTER)中有几位是很重要的设置,当我们选择指令系统或要用64位的MIPS的CPUCORE在32模式下(绝大多数情况,弟兄们别告诉我你在写64位的程序:
--))。
SR[XX]:
1:
MIPSIVINSTRUCTIONSETUSABLE
0:
MIPSIVINSTRUCTIONSETUNUSABLE
SR[KX]
SR[SX]
SR[UX]:
0:
CPU工作在32位模式下
1:
CPU工作在64位模式下
一般而言,如果你要从头写一个MIPS核心为32位程序,最好把上述值设为0。
为什么最好呢?
因为我在工作中没有去冒风险,设她们为1,whoknowswhatwouldhappen?
:
-)Andthenwhybother:
--)?
*在以后我们会单独的一章讲将流水线和指令系统,特别是跳转指令的关系。
在这里,我们只简单提一下。
对任何一个跳传指令后面,FORSIMPLITY,要加上一个空转指令(NOP)。
从而使得CPU的PIPELINE不会错误的执行一个预取(PRE_FETCH)得指令。
当然这个NOP可以替换为别的。
以后再讲。
放一个NOP是最简单和安全的。
有兴趣的读者可以用mips64-elf-objdump-d来反汇编一个
OBJECT文件。
你就会一目了然了。
*一定要记住:
MIPSI,II,III和IV指令系统不包含PRIVILEDGEDINSTRUCTIONS。
换句话说,都是那些在USERMODE下可以用的指令(当然KERNEL下也能用)。
对于CPO的操作不属于指令系统。
*有一点在MIPSCPU下,要千万注意:
ALIGN。
MIPS对ALIGN的要求是严厉的。
这一点与POWERPC是天壤之别。
指令必须是32位对齐。
数据类型必须在她们的的
大小边界对齐。
简单的比如:
WhenCPUrunningunder32bitmode,intmust32bitaligned;long32bitaligned;pointermustbe32bitaligned;charmust8bitaligned.longlongmust64bitaligned;关于这一点,我是吃过苦头的。
当然我知道大家还会犯错在这里:
--),即使知道了。
有些事情学是没用的:
--)。
一定要注意。
*我建议读者阅读SPECIFICATION时要花时间看一看指令系统的定义。
其实不难。
每一种指令不外乎几个域(FIELDS)。
寄存器约定
对于在一个CPU上进行开发,掌握其工作的CPU的寄存器约定是非常重要的。
MIPS体系结构提供了32个GPR(GENERALPURPOSEREGISTER)。
这32个寄存器的用法大致如下:
REGISTERNAMEUSAGE
$0$zero常量0(constantvalue0)
$2-$3$v0-$v1函数调用返回值(valuesforresultsandexpressionevaluation)
$4-$7$a0-$a3函数调用参数(arguments)
$8-$15$t0-$t7暂时的(或随便用的)
$16-$23$s0-$s7保存的(或如果用,需要SAVE/RESTORE的)(saved)
$24-$25$t8-$t9暂时的(或随便用的)
$28$gp全局指针(GlobalPointer)
$29$sp堆栈指针(StackPointer)
$30$fp帧指针(FramePointer)
(BNN:
fpisstaleacutally,andcanbesimplyusedas$t8)
$31$ra返回地址(returnaddress)
对一个CPU的寄存器约定的正确用法是非常重要的。
当然对C语言开发者不需要关心,因为COMPILER会TAKECARE。
但对于KERNEL的开发或DRIVER开发的人就**必须**清楚。
一般来讲,你通过objdump-d可以清醒的看到寄存器的用法。
下面通过我刚才写的一个简单例子来讲解:
~/viHello.c
"Hello.c"[Newfile]
/*Exampletoillustratemipsregisterconvention
*-Author:
BNN
*11/29/2001
*/
intaddFunc(int,int);
intsubFunc(int);
voidmain()
{
intx,y,z;
x=1;
y=2;
z=addFunc(x,y);
}
intaddFunc(intx,inty)
{
intvalue1=5;
intvalue2;
value2=subFunc(value1);
return(x+y+value2);
}
intsubFunc(intvalue)
{
returnvalue--;
}
上面是一个C程序,main()函数调用一个加法的子函数。
让我们来看看编译器是如何产生代码的。
~/bnn:
74>/bin/mips-elf-gcc-cHello.oHello.c-mips3-mcpu=r4000-mgp32-mfp32-O1
~/bnn:
75>/bin/mips64-elf-objdump-dHello.o
Hello.o:
fileformatelf32-bigmips
Disassemblyofsection.text:
/*mainFunction*/
0000000000000000:
/*createastackframebymovingthestackpointer8
*bytesdownandmeantimeupdatethespvalue
*/
0:
27bdfff8addiu$sp,$sp,-8
/*Savethereturnaddresstothecurrentspposition.*/
4:
afbf0000sw$ra,0($sp)
8:
0c000000jal0
/*nopisforthedelayslot*/
c:
00000000nop
/*Filltheargumenta0withthevalue1*/
10:
24040001li$a0,1
/*JumptheaddFunc*/
14:
0c00000ajal28
/*NOTEHERE:
Whywefillthesecondargument
*behindtheaddFuncfunctioncall?
*Thisisallaboutthe"-O1"compilationoptimizaiton.
*Withmipsarchitecture,theinstrucitonafterjump
*willalsobefetchedintothepiplineandget
*exectuted.Therefore,wecanpromisethatthe
*secondargumentwillbefilledwiththevalueof
*integer2.
*/
18:
24050002li$a1,2
/*Loadthereturnaddressfromthestackpointer
*Noteherethattheresultv0containstheresultof
*addFuncfunctioncall
*/
1c:
8fbf0000lw$ra,0($sp)
/*Return*/
20:
03e00008jr$ra
/*Restorethestackframe*/
24:
27bd0008addiu$sp,$sp,8
/*addFuncFunction*/
0000000000000028:
/*Createastackframebyallocating16bytesor4
*wordssize
*/
28:
27bdfff0addiu$sp,$sp,-16
/*Savethereturnaddressintothestackwith8bytes
*offset.Pleasenotethatcompilerdoesnotsavethe
*rato0($sp).
*Thinkofwhy,incontrastofthepreviousPowerPC
*EABIconvention
*/
2c:
afbf0008sw$ra,8($sp)
/*Wesavethes1reg.valueintothestack
*becausewewilluses1inthisfunction
*Notethatthe4,5,6,7($sp)positionswillthen
*beoccupiedbythis32bitssizeregister
*/
30:
afb10004sw$s1,4($sp)
/*Withesamereason,saves0reg.*/
34:
afb00000sw$s0,0($sp)
/*Retrievetheargument0intos0reg.*/
38:
0080802dmove$s0,$a0
/*Retrievetheargument1intos1reg.*/
3c:
00a0882dmove$s1,$a1
/*CallthesubFuncwitha0with5*/
40:
0c000019jal64
/*Inthedelayslot,weloadthe5intoargumenta0reg
*forsubFunccall.
*/
44:
24040005li$a0,5
/*s0=s0+s1;notethats0ands1holdsthevaluesof
*x,y,respectively
*/
48:
02118021addu$s0,$s0,$s1
/*v0=s0+v0;v0holdsthereturnresultsofsubFunc
*call;Andweletv0holdthefinalresults
*/
4c:
02021021addu$v0,$s0,$v0
/*Retrievetheravaluefromstack*/
50:
8fbf0008lw$ra,8($sp)
/*!
!
!
!
restorethes1reg.value*/
54:
8fb10004lw$s1,4($sp)
/*!
!
!
!
restorethes0reg.value*/
58:
8fb00000lw$s0,0($sp)
/*Returnbacktomainfunc*/
5c:
03e00008jr$ra
/*Update/restorethestackpointer/frame*/
60:
27bd0010addiu$sp,$sp,16
/*subFuncFunction*/
0000000000000064:
/*returnbacktoaddFuncfunction*/
64:
03e00008jr$ra
/*Takingadvantageofthemipsdelayslot,fillingthe
*resultregv0bysimplyassigningthev0asthevalue
*ofa0.Thisisabugfrommycsource
*codes--"value--".Ishouldwritemycodes
*like"--value",instead.
68:
0080102dmove$v0,$a0
希望大家静下心来把上面的代码看懂。
一定要注意编译器为什么在使用s0和s1之前要先把她们SAVE起来,然后再RESTORE,虽然在这个例子中虽然main函数没用s0和s1。
另外的一点是:
由于我们加了“-O1”优化,编译器利用了“delayslot"来执行那些必须执行的指令,而不是简单的塞一个”nop"指令在那里。
非常的漂亮。
最后,考大家一个问题,为了使得大家更加理解寄存器的用法:
*在写一个核心调度contextswitch()例程时,我们需要SAVE/RESTORE$t0-$t7吗?
如果不,为什么?
*在写一个时钟中断处理例程时,我们需要SAVE/RESTORE$t0-$t7吗?
如果是,为什么?
MMU和MemoryManagement
对于MIPS的MMU和MemoryManagement,thefirstandyetimportantoneweneed
always
keepinmindis:
Noreal-mode
没有实模式。
这一点是MIPSCPU的一个很重要的特点(或缺点)。
我们会问了:
BNN,Givemeabreak.WithoutCPUrunninginthereal-mode,
howcouldyoubootupakernel?
Well,hereisthething:
Bydefault,MIPSarchitecture,whenpoweron,hasenabled/mappedtwomemory
areas.Inotherwords,thosetwomemoryareasaretheplaceswhereyour
bootcodesHAVETOresidentandrunontopof.Ifyoureadthemakefiles
ofMIPSlinuxsourcetree,youwouldeasilyfindtheinfor.Forexample,
0x8000xxxxorsomethingslikethat.
*MIPS存储体系结构
我们在这里不谈64位CPU,只谈32位的。
MIPS将存储空间划分为4大块--kuseg,kseg0,kseg1andkseg2.
------------------------------------------------------------------
0xFFFFFFFF
mappedkseg2
0xC0000000
unmappeduncachedkseg1
0xA0000000
unmappedcachedkseg0
0x80000000
2Gkuseg
0x00000000
------------------------------------------------------------------
对于上述图表,弟兄们要记住以下几点:
*当开电(PowerOn)的时候,只有kseg0andkseg1是可以存取的。
*kseg0512M(From0x80000000to0xA0000000)areDIRECTLYmappedtophyiscal_
memoryrangingfrom0x00000000to0x20000000,withcache-able(eitherwrite
backorwritethrough,whichisdecidedbySR(StatusRegisterofMIPSCPU)_
*kseg1512M(From0xA0000000to0xC0000000)are(also)DIRECTLymapped
tophysicalmemoryrangingfrom0x00000000t00x20000000,withnon-cachable.
以上两点对于理解MIPSOS的启动是至关重要的。
细心的读者会发现:
kseg1有点象
其他CPU的real-mode方式。
*(虚拟)地址from0x00000000to0x80000000是不可以存取的,在加电时(POWER
ON)!
必须等到MMUTLB初始化之后才可以。
*同理对地址from0xC0000000to0xFFFF0000
*MIPS的CPU运行有3个态--UserMode;SupervisorModeandKernelMode.
Forsimplicity,let'sjust
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MIPS 体系结构