linux源码阅读笔记 jmpi指令(转)
jmpi是段间跳转指令,用于x86实模式下,
如:BOOTSEG = 0x0c70
jmpi 4, #BOOTSEG
假如当前段CS==00h,那么执行此指令后将跳转到段CS==0x0c70,当然段cs的值也变为0x0c70,接下来将执行指令0x0c70:0004处的指令。
实模式下寻址是为了兼容8086处理器,8086是16位CPU(是ALU的数据宽度),20位地址总线可寻址1M内存空间。其寻址方式:段基址+偏移 的方式,段基址保存在CS、DS、ES等段寄存器内,相当于寻址的高16位,而偏移是内部16位总线提供,在送往外部地址总线时,段基址和偏移合成20位地址,来寻址1M的物理地址空间。
合成方式:段基址左移4位,然后加上偏移地址。但还不是一般的相加,由于相加前段基址已经左移4位,变成20位了(最低4位是0),而偏移还是16位,所以,其实是段基址和偏移的高12位相加,偏移的低4位不变。
如:段基址左移4位后: 0x 8880:0
偏移地址(0x0440): + 0x 044 0
________________
外部总线20位地址: 0x88c4 0
可看出,这个所谓段式内存管理,并不是纯粹的基址加偏移的方式,据说这是Intel当时欺骗了大家。以下是,我看到的一篇文章中的说法:
8086/8088的寻址问题
===============
8088和80286都是16位CPU,Intel当初为什么会警告IBM和盖茨呢?到底发生了什么?
要了解发生了什么,我们要看看处理器的内部,会看到巨大的差异。首先,你找一片8088CPU,把包装磨掉,磨到CPU硅片,放到显微镜下,你会看到8086/88的内部结构,它根本不是一个新的设计,而是两个并联运行的8085(8位)微处理器再多那么一点点。
每个8085有它自己的8位数据和16位寻址能力。结合2个8位数据寄存器假装16位寄存器很容易。事实上这没有任何新东西,RCA COSMAC微处理器就使用16个8位寄存器,可作为内部的8位或16位寄存器使用,你可以有多达16个8位寄存器或8个16位寄存器或两者的任何组合。现在,一个中国的普通IC厂都可以轻易设计的出来。
可能由于受当时生产工艺所限,8088只能有40个脚,intel的设计“精英”左思右想,确定了20条地址线(1M的寻址空间),而且16条数据线还要和20条地址线中的16条复用(分时复用,即一会是地址线,一会是数据线,对此要想了解,可看8088芯片手册的时序部分,也可看8052单片机书籍,它的地址线和数据线也是复用的)。
到了问题的实质了,8088内的两个8085各有一套16位寻址寄存器,如何让他们寻址20位的1M地址呢?其实把他们并在一起形成32位寻址很简单,如果是那样后来的很多麻烦可能就都没有了(如A20门),但当时那些“精英”可能认为32位寻址(4G地址空间)那是扯淡,估计地球消失了也用不到那么多的内存吧?再说了老板逼的又紧,于是他们采用了在一个硬件上使用两个8085非常好实现的方法--分段:
他们把1024K地址空间分成16字节的段,共64K个段,用一个8085的16位寻址寄存器作地址偏移寄存器(故段的长度是64K),而另一个8085的16位寻址寄存器作16字节段的段地址寄存器,注意,他保存的不是16字节段的地址,而是16字节段的序号(0,1,...65535)。
这样做的好处是:只要在两8085CPU之间加一个移位器和一个20位的加法器,就可以完成20位的地址寻址--一个8085的地址寄存器(段地址--就是16字节段的序号)左移4位(*16 = 16字节小段的首地址),加上另一个8085的地址寄存器就可以啦,哈哈!可以向老板交差了,制作成本低,设计速度快,有钱不抢是孙子!至于以后,。。。。
linux源码阅读笔记 jmpi指令(转)的更多相关文章
- linux源码阅读笔记 数组定义
在阅读linux源码的过程中遇到了下面的略显奇怪的结构体数组定义. static struct hd_struct{ long start_sect; long nr_sects; }hd[10]={ ...
- linux源码阅读笔记 asm函数
在linux源码中经常遇到__asm__函数.它其实是函数asm的宏定义 #define __asm__ asm,asm函数让系统执行汇编语句. __asm__常常与__volatile__一起出现. ...
- linux源码阅读笔记 fork函数
在阅读源码的过程中,发现找不到fork函数的定义.后来在linux/init/main.c中找到了这样一条语句 static inline _syscall0(int,fork) 原来这里就是fork ...
- linux源码阅读笔记 move_to_user_mode()解析
在linux 0.11版本源代码中,在文件linux/include/asm/system.h中有一个宏定义 move_to_user_mode() 1 #define move_to_user_m ...
- linux源码阅读笔记 void 指针
void 指针的步长为1,而其他类型的指针的步长与其所定义的数据结构有关. example: 1 #include<stdio.h> 2 main() 3 { 4 int a[10]; 5 ...
- linux源码阅读笔记 #define 语句的妙用
#define 语句用于宏定义,在c中,我们可以用其实现函数的功能.如下语句 #define test(a,b) a>b?a:b 很显然,这是一个比较大小的语句.这里a,b相当于函数中的参数. ...
- Linux 0.11源码阅读笔记-中断过程
Linux 0.11源码阅读笔记-中断过程 是什么中断 中断发生时,计算机会停止当前运行的程序,转而执行中断处理程序,然后再返回原被中断的程序继续运行.中断包括硬件中断和软件中断,硬中断是由外设自动产 ...
- Linux 0.11源码阅读笔记-文件管理
Linux 0.11源码阅读笔记-文件管理 文件系统 生磁盘 未安装文件系统的磁盘称之为生磁盘,生磁盘也可以作为文件读写,linux中一切皆文件. 磁盘分区 生磁盘可以被分区,分区中可以安装文件系统, ...
- Linux 0.11源码阅读笔记-总览
Linux 0.11源码阅读笔记-总览 阅读源码的目的 加深对Linux操作系统的了解,了解Linux操作系统基本架构,熟悉进程管理.内存管理等主要模块知识. 通过阅读教复杂的代码,锻炼自己复杂项目代 ...
随机推荐
- 洛谷 1865 A%B问题
题目背景 题目名称是吸引你点进来的 实际上该题还是很水的 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行,每行两个整数 l,r 表示区间 输出格式: 对 ...
- josephus问题
问题描述 n个人围成一圈,号码为1-n,从1开始报数,报到2的退出,剩下的继续从1开始报数,求最后一个人的号码. 算法分析 最直观的算法是用循环链表模拟.从首节点开始,不断删除第二个节点,直到只剩一个 ...
- adb连接不上手机
昨天电脑重装了系统,今天打开之前的eclips工作环境,点击run as -> android application,一直报各种诡异的错误,总之就是连接不上手机. 其中包括 Adb conne ...
- brewhome - 第三方包管理工具
最近对移动开发感兴趣,于是乎有了相当正式的理由购买了一台macbook pro 13. 我虽然以前没有使用过mac os,但是上手却很快,这大概跟我最近几年一直在使用linux系统有关吧.我平时上班时 ...
- 《ISCSI集中存储》RHEL6——CE
集中存储的作用: 服务端的多余的分区,客户端可以拿来存储数据,并且所存储的数据直接写在服务器的硬盘上,当客户端A崩溃时,其他客户端依旧可以从服务器端访问到客户端A存储的数据. 服务器配置: Iptab ...
- VHDL基本常识
std_logic_vector和integer需要通过signed或unsigned进行间接转换(强制转换) a_std <= std_logic_vector(to_unsigned(a_i ...
- 【WinForm】“System.Data.SqlClient.SqlConnection”的类型初始值设定项引发异常,无法识别的配置节 system.serviceModel
出现问题的原因: 在本机上没有出现问题,让一个同事测试的时候,在另外一台电脑上出现连接数据库失败,系统不能打开的问题 在网上搜了一下,有说是数据库连接字符串错误的,有说app.config文件配置不匹 ...
- hadoop分布式安装过程
一.安装准备及环境说明 1.下载hadoop-1.2.1,地址:http://apache.spinellicreations.com/hadoop/common/stable/hadoop-1.2. ...
- Android SDK 更新失败
万恶的墙,调查兵团赶紧把墙拆了.大家一起跟巨人打一架. 解决方法是改hosts文件 添加 74.125.237.1 dl-ssl.google.com ok,good job 多亏了http://bl ...
- 一个好用的PHP验证码类
分享一个好用的php验证码类,包括调用示例. 说明: 如果不适用指定的字体,那么就用imagestring()函数,如果需要遇到指定的字体,就要用到imagettftext()函数.字体的位置在C盘下 ...