06 | x86架构:有了开放的架构,才能打造开放的营商环境
06 | x86架构:有了开放的架构,才能打造开放的营商环境
讲述:刘超
时长17:55大小16.37M
计算机的工作模式是什么样的?
x86 成为开放平台历史中的重要一笔
从 8086 的原理说起
再来说 32 位处理器
总结时刻
课堂练习
赞 85
提建议
精选留言(172)
- 一命赌快乐置顶2019-04-08move a b :把b值赋给a,使a=b call和ret :call调用子程序,子程序以ret结尾 jmp :无条件跳 int :中断指令 add a b : 加法,a=a+b or :或运算 xor :异或运算 shl :算术左移 ahr :算术右移 push xxx :压xxx入栈 pop xxx: xxx出栈 inc: 加1 dec: 减1 sub a b : a=a-b cmp: 减法比较,修改标志位展开
作者回复: 赞,认真学习的典范
共 4 条评论285 - Frank_512019-04-08作为一个搞硬件的,这章是我学习最轻松的,推荐一个入门的系统学习汇编的视频课,网易云课堂上的一个课程,《汇编从零开始到C语言》,通俗易懂,小白入门必备
作者回复: 推荐书籍
共 6 条评论111 - why2019-04-10- CPU 包括: 运算单元, 数据单元, 控制单元 - 运算单元 不知道算哪些数据, 结果放哪 - 数据单元 包括 CPU 内部缓存和寄存器, 暂时存放数据和结果 - 控制单元 获取下一条指令, 指导运算单元取数据, 计算, 存放结果 - 进程包含代码段, 数据段等, 以下为 CPU 执行过程: - 控制单元 通过指令指针寄存器(IP), 取下一条指令, 放入指令寄存器中 - 指令包括操作和目标数据 - 数据单元 根据控制单元的指令, 从数据段读数据到数据寄存器中 - 运算单元 开始计算, 结果暂时存放到数据寄存器 - 两个寄存器, 存当前进程代码段和数据段起始地址, 在进程间切换 - 总线包含两类数据: 地址总线和数据总线 --- - x86 开放, 统一, 兼容 - 数据单元 包含 8个 16位通用寄存器, 可分为 2个 8位使用 - 控制单元 包含 IP(指令指针寄存器) 以及 4个段寄存器 CS DS SS ES - IP 存放指令偏移量 - 数据偏移量存放在通用寄存器中 - `段地址<<4 + 偏移量` 得到地址 --- - 32 位处理器 - 通用寄存器 从 8个 16位拓展为 8个 32位, 保留 16位和 8位使用方式 - IP 从 16位扩展为 32位, 保持兼容 - 段寄存器仍为 16位, 由段描述符(表格, 缓存到 CPU 中)存储段的起始地址, 由段寄存器选择其中一项 - 保证段地址灵活性与兼容性 --- - 16位为实模式, 32位为保护模式 - 刚开机为实模式, 需要更多内存切换到保护模式展开共 4 条评论69
- TaoLR2019-04-08妥妥地复习了一把“计算机体系结构”🌹
作者回复: 后面很多地方要用到寄存器,所以必须先讲一下
52 - 谭2019-04-08老师讲地太精彩了 点赞。由于基础弱,还有几个问题希望老师万忙中答疑一下,谢谢: 问题1:程序编译成二进制代码的时候,包含有指令起始地址吗?若包含那么后续每一行指令的涉及到的指令地址是计算出来的? 或者说加载进程的程序的时候才会确定起始地址?很好奇这个指令的指针寄存器里的值是什么时候、怎么放进去的? 问题2: CPU两个寄存器处理保存当前进程代码段的起始地址,已经数据起始地址。切换进程时会将这两个寄存器里的值一并切换,那么同一个进程出现多线程的时候了? 问题3:数据总线拿数据的时候没有限制大小吗,若数据很大,数据单元里的数据寄存器放不下怎么办的?展开
作者回复: 1.会有指令起始地址,后面讲ELF格式的时候会说这个事情。当执行一个程序的时候,会加载ELF格式,加载的时候会设置指令指针 2.多线程共享同一个进程内存空间,所以代码段的起始地址还是一样的。只不过每个线程执行不同的func,指令指针会不一样,在内核中,线程也是有独立的task_struct 3.寄存器是有限的,如果把程序编译成汇编看的话,再大的数据,也是要转换为对寄存器的操作。当然寄存器里面可以包含对内存的访问地址,这样内存里面的数据就很多了
32 - why2019-04-08Guide to x86 Assembly: http://www.cs.virginia.edu/~evans/cs216/guides/x86.html
作者回复: 赞
30 - 微秒2019-04-08当然为了快速拿到段起始地址,段寄存器会从内存中拿到 CPU 的描述符高速缓存器中。 这句话感觉有点语义不通啊,能否详细解释下???
作者回复: 首先先建立一个观念,CPU里面的比内存块很多,内存比硬盘快很多。原来段的起始地址是放在寄存器里面的,所以速度就比在内存里面快很多,但是到了保护模式下,端起始地址放到内存里面了,就慢了,怎么办呢?将内存中的段描述符拿到CPU内的高速缓存中,就又快了。
共 4 条评论30 - 佳佳大魔王2019-04-08实模式和保护模式的英文中模式应该为pattern吧,另外这两个模式不太理解。
作者回复: 可以理解为,CPU和操作系统的一起干活的模式,在实模式下,两者约定好了这些寄存器是干这个的,总线是这样的,内存访问是这样的,在保护模式下,两者约定好了这些寄存器是干那个的,总线是那样的,内存访问是那样的。这样操作系统给CPU下命令,CPU按照约定好的,就能得到操作系统预料的结果,操作系统也按照约定好的,将一些数据结构,例如段描述符表放在一个约定好的地方,这样CPU就能找到。两者就可以配合工作了。
23 - 马上想好2019-04-09老师您好,我想问下 为什么高16位分成两个8位就不兼容列呀。
作者回复: 没有人写程序用高位的
共 4 条评论22 - 尚墨2019-04-10上周看了 Go 夜读社区 《Go Plan 9汇编入门》https://www.bilibili.com/video/av46494102 听的云里雾里的,在来看这篇文章好像感觉出了点门道。
作者回复: 呜哇,没想到能和go联系在一起,看来底层原理比较容易互通
17 - Pluto2019-04-08原来 x86 架构是指 8086 ,而 x86 是代表 32 位操作系统是因为 80386,原来这两个 x86 不是同一个意思啊,以前学操作系统的时候一直想不明白 x86 为什么是指代 32 位操作系统
作者回复: 哈哈
共 3 条评论17 - MJ2019-04-08“起始地址 *16+ 偏移量”,也就是把 CS 和 DS 中的值左移 4 位,变成 20 位的,加上 16 位的偏移量,这样就可以得到最终 20 位的数据地址。 求问老师,左移四位,如何理解?
作者回复: 就是乘以十六
共 3 条评论17 - 心浮天空2019-10-17实模式和保护模式的区别不知道理解的对不对, 1. 实模式下, 地址总线最大可寻地址空间大小仍为1M 2. 实模式下, 虽然通用寄存器和 IP寄存器在32CPU里已经扩展成32位, 但仍然只使用低16位 3. 实模式下, CS,DS,SS,ES寄存器仍段起始地址, 而在保护模式下实际指向的是段描述符位置 4. 实模式下, 没有特权等级和访问边界校验 5. 实模式下, 是直接对物理地址进行寻址, 没有虚拟地址和分页展开16
- 做一个积极的跳蚤2020-06-17听刘老师的课程,相信有基础都听得明白,但是要让自己再清晰的说出来,估计过一天后就说的模模糊糊吧。相信这是没有认真总结的学习的后果,导致后面随着时间就慢慢淡忘了,只记得个大概了。就像我某次面试一样,以前优化一个时间轮的数据结构,后面面试提到了,我一下想不起来就没回答清楚。知识常用常新,不常用就得经常回顾总结。 1.cpu的组成: 运算单元,数据单元,控制单元构成 运算单元负责程序代码段的运算; 数据单元由cpu内部缓存和寄存器组成,存储运算单元计算的需要的临时数据和运算结果; 控制单元控制运算单元执行哪条代码段指令,指导计算单元取数据、计算以及存放结果; 2.cpu如何执行程序、操作程序数据、产生结果并写回内存呢? 通过cpu控制单元中的指令指针寄存器(IP),不断取下一条内存代码段指令,放入指令寄存器。 指令分为两部分,一部分是指示操作类型(加,减等),一部分目标数据在数据段的地址; 要执行一条指令,就把操作交给运算单元,把对象数据地址交给数据单元。 数据单元根据控制单元指令,从内存中的数据段读数据到的寄存器,然后运算单元进行运算。 产生的结果暂存数据单元的寄存器,最后控制单元根据指令将数据写回内存中的数据段; 3.cpu进程切换 cpu有两个寄存器,存放当前进程代码段起始地址、数据段的起始地址,当前进程A就存放A的,切换到B就存的是B的; 4.总线包括数据总线和地址总线 5.x86 16位8086经典cpu,现在cpu大部分兼容继承它。 数据单元 包含8个16位通用寄存器(AX、BX、CX、DX、SP、BP、SI、DI),用于计算过程中暂存数据,前4个可分为高低两个8位使用。 控制单元 包含 IP(指令指针寄存器) 以及 4个16位段寄存器 CS DS SS ES; IP 寄存器,存放指令偏移量,指向下一条指令位置。 CS 代码段寄存器,存代码段开始地址;DS是数据段寄存器,存数据段开始地址; SS 是栈寄存器,栈是程序运行中特殊数据结构,先进后出,函数调用就是栈的结构。 CS DS存放各自开始地址,代码段偏移量在IP寄存器中,数据段偏移地址存放通用寄存器中; 8086地址总线20位,CS,DS都是16位,通过“起始地址 *16+ 偏移量”来支持 6.x86 32位cpu,可访问2^32=4G内存 通用寄存器 从 8个 16位拓展为 8个 32位, 保留 16位和 8位使用方式 IP 寄存器从 16位扩展为 32位, 保持兼容 变化最大的段寄存器,为兼容仍是16位,但不再是段起始地址,段起始地址在内存中以表格存在, 表格中是段描述符,这里面才是真正段其实地址,而段寄存器中保存选择子指明是哪个描述符。 为了加速拿到其实地址,段寄存器会从内存中拿到 CPU 的描述符到高速缓存器中。 7.实模式、保护模式 16位为实模式, 32位为保护模式; 刚开机为实模式,当运行需要更多内存和更多操作时候就是保护模式,通过切换模式实现cpu兼容展开13
- Matnix2019-04-11结合《深入理解计算机系统》第三章,受益匪浅
作者回复: 这本书值得推荐
13 - YoungMarshual_besos2019-04-08几乎完全看懵了,发现基础知识极其匮乏,努力补课,夯实根基太重要了。
作者回复: 补充完再看,可以看看计算机组成与系统结构
12 - TinnyFlames2019-04-08x86是甜蜜的历史包袱,它的兼容性让它一统市场,但是当时很多性能上更好的尝试在商业上都失败了,因为兼容性的问题客户不买单……
作者回复: 是的,所以兼容比优雅要重要
12 - MARK2019-04-08已经有童鞋回复,再补充点 MOV: load value. this instruction name is misnomer, resulting in some confusion (data is not movedbut copied), in other architectures the same instructions is usually named “LOAD” and/or “STORE”or something like that.One important thing: if you set the low 16-bit part of a 32-bit register in 32-bit mode, the high 16bits remains as they were. But if you modify the low 32-bit part of the register in 64-bit mode, thehigh 32 bits of the register will be cleared.Supposedly, it was done to simplify porting code to x86-64. CALL:call another function:PUSH address_after_CALL_instruction; JMP label. JMP: jump to another address. The opcode has ajump offset. INT(M):INT x is analogous to PUSHF; CALL dword ptr [x*4]in 16-bit environment. It was widely used in MS-DOS, functioning as a syscall vector. The registers AX/BX/CX/DX/SI/DI were filled with the arguments and then the flow jumped to the address in the Interrupt Vector Table (located at thebeginning of the address space). It was popular because INT has a short opcode (2 bytes) and the program which needs some MS-DOS services is not bother to determine the address of the service’sentry point. The interrupt handler returns the control flow to caller using the IRET instruction.The most busy MS-DOS interrupt number was 0x21, serving a huge part of itsAPI. In the post-MS-DOS era, this instruction was still used as syscall both in Linux and Windows (6.3 onpage 750), but was later replaced by the SYSENTER or SYSCALL instructions. RET: return from subroutine:POP tmp; JMP tmp. In fact, RET is an assembly language macro, in Windows and *NIX environment it is translated into RETN (“return near”) or, in MS-DOS times, where the memory was addressed differently, into RETF (“return far”). RET can have an operand. Then it works like this: POP tmp; ADD ESP op1; JMP tmp.RETwith an operand usually ends functions in the stdcall calling convention.展开11
- GivenCui2021-03-16AH&AL=AX(accumulator)累加寄存器 BH&BL=BX(base)基址寄存器 CH&CL=CX(count)计数寄存器 DH&DL=DX(data)数据寄存器 SP(Stack Pointer)堆栈指针寄存器 BP(Base Pointer)基址指针寄存器 SI(Source Pointer)源变址寄存器 DI(Destination Index)目的变址寄存器 IP(Instruction Pointer)指令指针寄存器 CS(Code Segment)代码段寄存器 DS(Data Segment)数据段寄存器 SS(Stack Segment)堆栈段寄存器 ES(Extra Segment)附加段寄存器展开10
- 布凡2019-04-12本文结构:https://www.cnblogs.com/bindot/p/linux6.html共 1 条评论9