通用寄存器

c coroutine

半世苍凉 提交于 2020-01-12 23:52:34
今天看了下云风写的关于 c coroutine 博客 ( 代码 ), 发现 coroutine 实现原理其实还比较简单,就用户态栈切换,只需要几十行汇编,特别轻量级。 具体实现 1. 创建一个coroutine: 也就是创建一块连续内存,用于存放栈空间,并设置好入口函数所需要的寄存器   makecontext glibc c语言实现 2. resume coroutine: push保存当前执行上下文的寄存器到栈上,修改%rsp寄存器, jmp 到指定coroutine 执行指令位置,pop 恢复寄存器,开始执行 swapcontext glibc 汇编实现 3. yield coroutine: 同resume 栈切换涉及寄存器操作,得用汇编实现, x86 8个通用寄存器,x64 16个,通过push 保存到栈,pop 恢复到寄存器;比较重要寄存器%rsp 栈顶指针,%rip 指令指针不能直接操作,通过call、jmp 跳转新的Code执行位置。 在64汇编中,并不需要对16个寄存器都备份,其中%rax作为返回值、%r10 %r11 被调用方使用前会自己备份. 参考: X86-64寄存器和栈帧 X86-64寄存器的变化,不仅体现在位数上,更加体现在寄存器数量上。新增加寄存器%r8到%r15。加上x86的原有8个,一共16个寄存器。 刚刚说到,寄存器集成在CPU上

深入理解计算机系统(3.4)------算术和逻辑操作

微笑、不失礼 提交于 2020-01-11 23:48:03
上一篇博客 我们介绍了几种数据传送指令,包括MOV,MOVS,MOVZ,PUSH和POP等,理解起来也不算难。本篇博客我们来接着看汇编语言的算术与逻辑运算指令,算术无非就是加减乘除,而逻辑运算也就是与或非,移位等操作。下面这张图是汇编里面的算术和逻辑操作:      上面除了 leal(加载有效地址)指令通常用来执行简单的算术操作,其余的指令都是标准的一元或者二元操作,下面我们分别来介绍这几个指令操作。 1、leal 指令   leal 指令也称为加载有效地址(load effective address)指令,它实际上是 movl 指令的变形。它的指令形式是从存储器读数据到寄存器,但实际上它根本没有引用存储器。   它的第一个操作数看上去是一个存储器引用,但该指令并不是从指定的位置读取数据,而是将有效地址写入到目的操作数,类似于 C 语言的取地址操作符“&”。另外就是作普通的算术运算。   leal 立即数,寄存器   这类指令就是将立即数装载至寄存器,比如 leal $0x01,%eax 这种情况下 和 movl $0x01,%eax 的效果是等价的    leal 地址,寄存器   leal指令的作用是将地址加载到寄存器,对于leal S,D而言,就是实现了 &S –> D 的功能    leal S, D 结果是&S -> D   movl S,D 结果是S -> D   

计算机基础系列一:计算机硬件

微笑、不失礼 提交于 2020-01-10 08:14:29
1、编程语言的作用及与操作系统和硬件的关系   一个完整的计算机系统包括硬件、操作系统、软件(即程序员开发的各种软件)三部分组成。   各程序员开发的软件若直接调用计算机的硬件,如硬盘读取、音频播放等,则软件不仅编写复杂同时影响开发效率,因此程序员开发的软件需通过计算机操作系统间接调用计算机各硬件。如下图:    即编写各种计算机软件的编程语言可看作程序员与计算机沟通的介质,程序员通过编程语言编写软件从而达到控制计算机的目的。 2、计算机硬件   计算机硬件(Computer hardware)是指计算机系统中由电子,机械和光电元件等组成的各种物理装置的总称。简言之,计算机硬件是构成计算机的物质基础,是计算机系统的核心。从外观上来看,微机由主机箱和外部设备组成。   根据计算机之父冯·诺依曼的划分,计算机由运算器、控制器、存储器、输入设备、输出设备五部分组成。 通常把运算器与控制器合称为中央处理器( Central Processing Unit ,CPU )。 其中: CPU是计算机的核心,负责计算机的运算及程序控制; 存储器是计算机的记忆设备,用来存放程序和数据 输入设备是计算机接收外部信息和数据的设备。常用输入设备有:键盘、鼠标、扫描仪等 输入设备是输出计算机处理后的数据。常用的输出设备有:显示器、打印机等 在计算机中,计算机各硬件是通过各类总线连接在一起的。 2.1处理器

【转贴】GCC 内联汇编

旧巷老猫 提交于 2020-01-10 04:55:40
1. 简介 1.1 版权许可 Copyright (C) 2003 Sandeep S. 本文档自由共享;你可以重新发布它,并且/或者在遵循自由软件基金会发布的 GNU 通用公共许可证下修改它;也可以是该许可证的版本 2 或者(按照你的需求)更晚的版本。 发布这篇文档是希望它能够帮助别人,但是没有任何担保;甚至不包括可售性和适用于任何特定目的的担保。关于更详细的信息,可以查看 GNU 通用许可证。 1.2 反馈校正 请将反馈和批评一起提交给 Sandeep.S。我将感谢任何一个指出本文档中错误和不准确之处的人;一被告知,我会马上改正它们。 1.3 致谢 我对提供如此棒的特性的 GNU 人们表示真诚的感谢。感谢 Mr.Pramode C E 所做的所有帮助。感谢在 Govt Engineering College 和 Trichur 的朋友们的精神支持和合作,尤其是 Nisha Kurur 和 Sakeeb S 。 感谢在 Gvot Engineering College 和 Trichur 的老师们的合作。 另外,感谢 Phillip , Brennan Underwood 和 colin@nyx.net ;这里的许多东西都厚颜地直接取自他们的工作成果。 2. 概览 在这里,我们将学习 GCC 内联汇编。这里内联表示的是什么呢?

深入理解计算机系统(3.4)------算术和逻辑操作

拟墨画扇 提交于 2020-01-10 01:50:15
  上一篇博客 我们介绍了几种数据传送指令,包括MOV,MOVS,MOVZ,PUSH和POP等,理解起来也不算难。本篇博客我们来接着看汇编语言的算术与逻辑运算指令,算术无非就是加减乘除,而逻辑运算也就是与或非,移位等操作。下面这张图是汇编里面的算术和逻辑操作:      上面除了 leal(加载有效地址)指令通常用来执行简单的算术操作,其余的指令都是标准的一元或者二元操作,下面我们分别来介绍这几个指令操作。 1、leal 指令   leal 指令也称为加载有效地址(load effective address)指令,它实际上是 movl 指令的变形。它的指令形式是从存储器读数据到寄存器,但实际上它根本没有引用存储器。   它的第一个操作数看上去是一个存储器引用,但该指令并不是从指定的位置读取数据,而是将有效地址写入到目的操作数,类似于 C 语言的取地址操作符“&”。另外就是作普通的算术运算。   leal 立即数,寄存器   这类指令就是将立即数装载至寄存器,比如 leal $0x01,%eax 这种情况下 和 movl $0x01,%eax 的效果是等价的    leal 地址,寄存器   leal指令的作用是将地址加载到寄存器,对于leal S,D而言,就是实现了 &S –> D 的功能    leal S, D 结果是&S -> D   movl S,D 结果是S -> D

在复杂模型机上编写机器指令与微程序计算海伦公式——计算机组成原理课程设计

元气小坏坏 提交于 2020-01-09 03:59:26
文章目录 一、实验内容 1. 实验目的 2. 实验目标 3.实验设备 二、实验原理 1)数据格式 2)指令设计 3)指令格式 4)指令系统 三、总体设计 四、实验步骤 1. 按图6连接实验线路,仔细检查连线后打开实验箱电源。 2. 写入实验程序,并进行校验。 3. 运行程序 五、实验结果 六、实验中遇到的问题与分析 一、实验内容 1. 实验目的 综合运用所学计算机组成原理知识,设计并实现较为完整的计算机。 2. 实验目标 在充分理解复杂模型机原理的基础上,自行编写机器指令及其对应的微程序,达到使用复杂模型机计算海伦公式的目标。 3.实验设备 PC机一台,TD-CMA实验系统一套。 二、实验原理 1)数据格式 此次使用的模型机规定采用定点补码表示法表示数据,字长为8位,8位全用来表示数据(最高位不表示符号),数值表示范围是:0≤X≤2 8 -1。 2)指令设计 根据海伦公式计算中所需要的指令,设计三大类模型机指令共十五条,其中包括运算类指令、控制转移类指令、数据传送类指令。 运算类指令包含三种运算,算术运算、逻辑运算和移位运算,设计有 6 条运算类指令,分别为:ADD、AND、DEC、SUB、OR、SAR,所有运算类指令都为单字节,寻址方式采用寄存器直接寻址。 控制转移类指令有三条 HLT、JMP、BZC,用以控制程序的分支和转移,其中HLT 为单字节指令,JMP和BZC为双字节指令

FreeRTOS 任务栈大小确定及其溢出检测

ε祈祈猫儿з 提交于 2020-01-06 01:42:22
以下转载自安富莱电子: http://forum.armfly.com/forum.php FreeRTOS 的任务栈设置 不管是裸机编程还是 RTOS 编程,栈的分配大小都非常重要。 局部变量,函数调用时的现场保护和返 回地址,函数的形参,进入中断函数前和中断嵌套等都需要栈空间,栈空间定义小了会造成系统崩溃。 裸机的情况下,用户可以在这里配置栈大小: 为什么是堆中的?因为我们采用的就是动态创建任务的方式。如果静态创建,就和我们自己开辟的空间有关,通常静态创建任务用数组作为容器,但是通常静态创建的方式我们都不使用。 FreeRTOS 的系统栈设置 上面跟大家讲解了什么是任务栈,这里的系统栈又是什么呢?裸机的情况下,凡是用到栈空间的地方 都是在这里配置的栈空间: 在 RTOS 下, 上面两个截图中设置的栈大小有了一个新的名字叫系统栈空间 ,而任务栈是不使用这里的空间的。 任务栈不使用这里的栈空间,哪里使用这里的栈空间呢?答案就在中断函数和中断嵌套。  由于 Cortex-M3 和 M4 内核具有双堆栈指针,MSP 主堆栈指针和 PSP 进程堆栈指针,或者叫 PSP 任务堆栈指针也是可以的。在 FreeRTOS 操作系统中,主堆栈指针 MSP 是给系统栈空间使用的,进 程堆栈指针 PSP 是给任务栈使用的。 也就是说,在 FreeRTOS 任务中,所有栈空间的使用都是通过 PSP

汇编语言---GCC内联汇编

我怕爱的太早我们不能终老 提交于 2020-01-05 09:57:48
GCC支持在C/C++代码中嵌入汇编代码,这些代码被称作是"GCC Inline ASM"(GCC内联汇编); 一、基本内联汇编 GCC中基本的内联汇编非常易懂, 格式如下 : __asm__ [__volatile__] ("instruction list"); 其中, 1.__asm__ : 它是GCC定义的关键字 asm 的宏定义(#define __asm__ asm),它用来声明一个内联汇编表达式,所以,任何一个内联汇编表达式都以它开头,它是必不可少的;如果要编写符合ANSI C标准的代码(即:与ANSI C兼容),那就要使用__asm__; 2.__volatile__ : 它是GCC关键字 volatile 的宏定义;这个选项是可选的;它向GCC声明"不要动我所写的instruction list,我需要原封不动地保留每一条指令";如果不使用__volatile__,则当你使用了优化选项-O进行优化编译时,GCC将会根据自己的判断来决定是否将这个内联汇编表达式中的指令优化掉;如果要编写符合ANSI C标准的代码(即:与ANSI C兼容),那就要使用__volatile__; 3.instruction list : 它是汇编指令列表;它可以是空列表,比如:__asm__ __volatile__("");或__asm__("");都是合法的内联汇编表达式

【转贴】GCC 内联汇编

坚强是说给别人听的谎言 提交于 2020-01-05 09:56:10
1. 简介 1.1 版权许可 Copyright (C) 2003 Sandeep S. 本文档自由共享;你可以重新发布它,并且/或者在遵循自由软件基金会发布的 GNU 通用公共许可证下修改它;也可以是该许可证的版本 2 或者(按照你的需求)更晚的版本。 发布这篇文档是希望它能够帮助别人,但是没有任何担保;甚至不包括可售性和适用于任何特定目的的担保。关于更详细的信息,可以查看 GNU 通用许可证。 1.2 反馈校正 请将反馈和批评一起提交给 Sandeep.S。我将感谢任何一个指出本文档中错误和不准确之处的人;一被告知,我会马上改正它们。 1.3 致谢 我对提供如此棒的特性的 GNU 人们表示真诚的感谢。感谢 Mr.Pramode C E 所做的所有帮助。感谢在 Govt Engineering College 和 Trichur 的朋友们的精神支持和合作,尤其是 Nisha Kurur 和 Sakeeb S 。 感谢在 Gvot Engineering College 和 Trichur 的老师们的合作。 另外,感谢 Phillip , Brennan Underwood 和 colin@nyx.net ;这里的许多东西都厚颜地直接取自他们的工作成果。 2. 概览 在这里,我们将学习 GCC 内联汇编。这里内联表示的是什么呢?

CS萌新的汇编学习之路02 Learning of Assembly Language

青春壹個敷衍的年華 提交于 2020-01-02 06:28:08
第二节课 寄存器 1. 寄存器的定义: 进行信息储存的器件,是CPU中程序员可以读写的部件,通过改变各种寄存器中的内容来实现对CPU的控制 2. 寄存器的种类: 本节课学习通用寄存器和段寄存器 2.1 通用寄存器 8086CPU中,所有的寄存器都是16位的,可以存放两个字节。AX,BX,CX,DX这四个寄存器通常用来存放一般性的数据,被称为通用寄存器。 8086CPU的上一代CPU中的寄存器都是8位的,为了保证兼容,AX,BX,CX,DX这四个寄存器都可以分为两个8位的小寄存器来用。8086CPU可以一次性处理字节和字,字节(byte)是8个bit组成;字(word)是由两个字节组成(高位字节和低位字节) 例如,AX分为AH和AL (高位和低位)AH为高8位,从00H到FFH,AL为低8位,从00H到FFH。两个按照AX=AH*100H+AL组合在一起。但是在对于AL、AH的单独运算中,产生进位是不予考虑的,比如单独对AL做加法,产生的进位不会加到AH里面,AH的进位也不予添加(超出AX范围了)。但是对于AX的计算考虑在AX范围内的进位,超出AX范围不考虑(直接舍去)。 2.2 物理地址和计算物理地址的方法 CPU访问内存单元,需要给出内存单元的地址,这个唯一的地址为物理地址。 8086CPU为16位结构的CPU机,意味着运算器一次性最多能处理16位的数据,寄存器的最大宽度为16