cpu第一条指令

转自:http://blog.csdn.net/lightseed/article/details/4735101


1、准备知识

如果您还对Flat mode的原理还不太了解的话,那么我想你可以再回头参考一下关于Flat mode的原理。见

http://blog.csdn.net/lightseed/archive/2009/07/01/4312834.aspx

在保护模式下,我们的段寄存器其实都是由两部分组成的:一步分是可见的段选择子(segment selector),另外一部分是隐藏的基地址(base address)。那么第一条指令就和这个密切相关。

2、CPU到哪里去取第一条指令

开门见山,当HW reset后,CPU会到(物理地址为)0FFFF FFF0H处去取指令并执行之。这个地址很明显是CPU的最高物理地址往下数16个bytes的地址处。BIOS的第一条指令必须要被放到这里,否则的话。。。后果可想而知。

3、为什么是这里

我想只要是刚入门的freshman都会感到比较疑惑,这个地址(FFFF FFF0H)明明是大于1-Mbyte的地址了,而此时的CPU却是在实模式下的,那么CPU是怎么到这里去取指令的呢?

3.1 原理

不过看完上面这段话的描述,我们是不是感觉有点亲切呢?再回忆一下,其实在我们之前的讨论中关于Flat mode的时候,就接触到个概念了。在Flat mode中的时候,虽然我们是处于实模式,但是由于我们的段寄存器(segment register)是由两个部分组成的,一部分是可见的段选择子,另外一部分是隐藏部分(段基地址)。如果我们在protect mode中修改好了段寄存器的段基地址部分,然后返回实模式,那么只要不显示地修改段寄存器,CPU在寻址的时候仍然会照protect mode下的寻址方式来计算地址,即:segment selector:offset。

3.2 BIST后CPU的状态

经过正确的power sequence后,CPU吃到CPURST#正常BIST(Built-In Self-Test)后,CPU其实就正是处于Flat mode中。(比较特殊的实模式)那么让我们来看看正常的BIST后,CPU的(部分)寄存器的状态吧。见图1。

 

图1 BIST后部分寄存器的值

 

图2 CPU关于CR0的bit定义

看清楚了图2中定义的CR0的bit0了么?PE,是指protect mode enable。那么我们再结合图1两个方框处关于CR0和CS的初始值,可以很清楚地看到这个时候CPU是处于实模式的,然而CS的Base却是等于FFFF0000H的,而且段界限是FFFFH,并且CS的选择子是等于F000H的。

3.3 详细计算

那这样以来,如果我们用CS:IP是用F000H:FFF0H的方式来操作的时候,CPU其实是会把地址这样算的。F000H是CS的段选择子,从这里取出CS的基地址(就是FFFF0000H)再加上IP的值(FFF0H)就等于实际要访问的内存地址(正好是FFFF FFF0H)[FFFF0000+FFF0H=FFFFFFF0H]。所以在32bit的CPU上,这个第一条指令的计算是这样来的。

不过一般情况下HW reset后,BIOS都会在第一条指令这里安排一个far jump来显示地修改CS的值,目的就是能够让CS真正进入real mode。就是让CS能够遵从正常的real mode的寻址翻译规则。(CS base address = CS segment selector * 16)。那至于后面的BIOS code的run的环境,我想大家就都应该了解了。

关于第一条指令的讲述Bini前辈也曾详细说明过,这里是连接供大家参考。

http://www.ufoit.com/bbs/thread-106-1-1.html




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是基于单周期MIPS CPU的Logisim设计的8条指令: 1. ADD指令:将两个寄存器的值相加,并将结果存储在第三个寄存器中。 操作码:000000 功能码:100000 格式:R型指令 示例:ADD $t0, $s0, $s1 2. SUB指令:将两个寄存器的值相减,并将结果存储在第三个寄存器中。 操作码:000000 功能码:100010 格式:R型指令 示例:SUB $t0, $s0, $s1 3. AND指令:将两个寄存器的值进行按位与操作,并将结果存储在第三个寄存器中。 操作码:000000 功能码:100100 格式:R型指令 示例:AND $t0, $s0, $s1 4. OR指令:将两个寄存器的值进行按位或操作,并将结果存储在第三个寄存器中。 操作码:000000 功能码:100101 格式:R型指令 示例:OR $t0, $s0, $s1 5. ADDI指令:将一个寄存器的值与一个常数相加,并将结果存储在另一个寄存器中。 操作码:001000 格式:I型指令 示例:ADDI $t0, $s0, 100 6. LW指令:将某个内存地址中的数据加载到寄存器中。 操作码:100011 格式:I型指令 示例:LW $t0, 0($s0) 7. SW指令:将寄存器中的数据存储到某个内存地址中。 操作码:101011 格式:I型指令 示例:SW $t0, 0($s0) 8. BEQ指令:如果两个寄存器的值相等,则跳转到指定的地址。 操作码:000100 格式:I型指令 示例:BEQ $t0, $s0, label 注意:以上指令仅供参考,实际应用中需要根据具体需求进行调整和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值