一步步编写操作系统 79 在c代码中内联汇编

基本内联汇编是最简单的内联形式,其格式为:

asm [volatile] (“assembly code”)

各关键字之间可以用空格或制表符分隔也可以紧凑挨在一起不分隔,各部分意义如下:

关键字asm用于声明内联汇编表达式,这是内联汇编固定的部分,不可少。

asm和__asm__是一样的,是由gcc定义的宏:#define __asm__ asm。

因为gcc有个优化选项-O,可以指定优化级别。当用-O来编译时,gcc按照自己的意图优化代码,说不定就会把自己所写的代码修改了。关键字volatile是可选项,它告诉gcc:“不要修改我写的汇编代码,请原样保留”。volatile和__volatile__是一样的,是由gcc定义的宏:#define __volatile__ volatile。

“assembly code”是咱们所写的汇编代码,它必须位于圆括号中,而且必须用双引号引起来。这是格式要求,只要满足了这个格式asm [volatile] (“”),assembly code甚至可以为空。

下面说下assembly code的规则:

  1. 1.指令必须用双引号引起来,无论双引号中是一条指令或多条指令。
  2. 2.一对双引号不能跨行,如果跨行需要在结尾用反斜杠’\’转义。
  3. 3.指令之间用分号’;’或换行符’\n’或换行符加制表符’\n’’\t’分隔。

提醒一下,即使是指令分布在多个双引号中,gcc最终也要把它们合并到一起来处理,合并之后,指令间必须要有分隔符。所以,当指令在多个双引号中时,除最后一个双引号外,其余双引号中的代码最后一定要有分隔符,这和其它编程语言中表示代码结束的分隔符是一样的,如:

asm(“movl $9,%eax;””pushl %eax”)正确

asm(“movl $9,%eax””pushl %eax”)错误

大家注意,在内联汇编中,咱们要注意操作数的顺序啦,现在是和intel反着的。

给大家举个例子,见文件inlineASM.c

 1	char* str="hello,world\n";2	int count = 0;3	void main(){4	 asm("pusha;	 \5		 movl $4,%eax;	 \6		 movl $1,%ebx;	 \7		 movl str,%ecx;	 \8		 movl $12,%edx;	\9		 int $0x80;	 \
10		 mov %eax,count; \
11		 popa		 \
12		 ");
13	}

代码inlineASM.c是演示用汇编代码直接调用“系统调用”write来打印字符患,该系统调用执行后会返回打印的字符数。

第1~2行定义了两个全局变量,待打印的字符串是str,count是用来存储返回值

第4~12行是内联汇编,这是咱们之前说过的c语言中跨过运行库直接调用系统调用的实例。这完全是AT&T风格的汇编语句:寄存器前面加前缀%,立即数前面加前缀$,操作数由左到右的顺序。似乎看上去很简单。

第4行将8个通用寄存器压栈,AT&T中的汇编指令是pusha(intel中的是pushad)。

第5行是传入第4号系统调用,这就是write的调用号。

第6~8行是为write系统调用传入参数,前面说系统调用的时候有讲过参数传递所用到的寄存器,不再赘述。

第9行用int 0x80执行系统调用,在AT&T中立即数的地位比较低,要加$前缀才表示数字为立即数(常数)。

第10行是获取write的返回值,返回值都是存储在eax寄存器中,所以将其复制到变量count中。

好啦,编译运行看结果,如图

 

大家注意到没有,inlineASM.c中的变量count和str是定义为全局变量。对的,在基本内联汇编中,若要引用c变量,只能将它定义为全局变量。如果定义为局部变量,链接时会找不到这两个符号,这就是基本内联汇编的局限性,简单的东西往往功能不够强大,所以咱们还得学下扩展内联汇编形式,下一节走起。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439275.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 237. 删除链表中的节点(思维)

请编写一个函数,用于 删除单链表中某个特定节点 。在设计函数时需要注意,你无法访问链表的头节点 head ,只能直接访问 要被删除的节点 。 题目数据保证需要删除的节点 不是末尾节点 。 https://leetcode-cn.com/problems/delete-node-in-a-…

LeetCode 397. 整数替换

题目大意: 给定一个正整数 n ,你可以做如下操作: 如果 n 是偶数,则用 n / 2替换 n 。 如果 n 是奇数,则可以用 n 1或n - 1替换 n 。 n 变为 1 所需的最小替换次数是多少? 链接:https://leet…

LeetCode 375. 猜数字大小 II

题目大意: https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii 我们正在玩一个猜数游戏,游戏规则如下: 我从 1 到 n 之间选择一个数字。 你来猜我选了哪个数字。 如果你猜到正确的数字,就会 赢得游戏 。 如果你…

【转】2.3SharePoint服务器端对象模型 之 访问网站和列表数据(Part 3)

(三)视图 与传统意义上的数据视图类似,SharePoint中的列表视图指定了列表中数据的筛选条件、排序条件、分组条件、显示栏/字段、显示条目数、显示样式等内容。在SharePoint中,使用SPView表示列表视图,使用SPViewColle…

【转】2.4SharePoint服务器端对象模型 之 访问网站和列表数据(Part 4)

(四)栏/字段 SharePoint中的字段(中文版中叫做“栏”)与传统的数据栏类似,也有不同类型的区别,不过SharePoint中内置的栏类型除了按照数据类型(如数字、日期和时间等)进行区分之外&…

【转】2.5SharePoint服务器端对象模型 之 访问网站和列表数据(Part 5)

(五)列表条目(SPListItem) SharePoint中数据的存储基本上都是通过列表条目来完成(文档库中的文档也是一种特殊的列表条目),因此在SharePoint应用开发中,最终是要和列表条目打交道的…

【转】3.3SharePoint服务器端对象模型 之 访问文件和文件夹(Part 3)

(三)遍历 文件系统的遍历是指按照文件夹的层级结构遍历文档库、列表的文件夹和列表条目。遍历主要有三种方式:(1)直接使用文件系统对象模型进行遍历;(2)使用SPDocumentLibrary进行遍…

【LeetCode240、剑指offer04】二维数组中的查找(线性做法)

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 示例: 现有矩阵 matrix 如下&#x…

【转】4.2SharePoint服务器端对象模型 之 使用CAML进行数据查询(Part 2)

(三)使用SPQuery进行列表查询 1、概述 列表查询主要是指在一个指定的列表(或文档库)中按照某些筛选、排序条件进行查询。列表查询主要使用SPQuery对象,以及SPList的GetItems方法,将SPQuery作为参数传递&a…

【转】理解SQL Server的安全对象和权限

理解安全对象(Securable) 安全对象,是SQL Server 数据库引擎授权系统控制对其进行访问的资源。通俗点说,就是在SQL Server权限体系下控制的对象,因为所有的对象(从服务器,到表,到视图触发器等)都在SQL Server的权限体系…

【NC14 按之字形顺序打印二叉树】

描述 给定一个二叉树&#xff0c;返回该二叉树的之字形层序遍历&#xff0c;&#xff08;第一层从左向右&#xff0c;下一层从右向左&#xff0c;一直这样交替&#xff09; 数据范围&#xff1a;0 \le n \le 15000≤n≤1500,树上每个节点的val满足 |val| < 100∣val∣<1…

SharePoint 2010文档库批量下载文档的实现

在SharePoint 2010文档库中&#xff0c;结合单选框&#xff0c;在Ribbon中提供了批量处理文档的功能&#xff0c;比如&#xff0c;批量删除、批量签出、批量签入等&#xff0c;但是&#xff0c;很遗憾&#xff0c;没有提供批量下载&#xff0c;如图: 若选中多个文档后&#xff…

【LeetCode - 42. 接雨水】

42. 接雨水 难度困难3164 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 […

【LeetCode】第283场周赛题解

本场题题目不难&#xff0c;但是力求写出精简优雅的代码&#xff0c;还是有需要学习的地方的。 第一题 力扣 class Solution:def cellsInRange(self, s: str) -> List[str]:ans []a,b,c,d s[0],s[1],s[3],s[4]for i in range(ord(a), ord(c)1):for j in range(int(b),int…

Linq to Sql : 三种事务处理方式

Linq to SQL支持三种事务处理模型&#xff1a;显式本地事务、显式可分发事务、隐式事务。(from MSDN: 事务 (LINQ to SQL))。MSDN中描述得相对比较粗狂&#xff0c;下面就结合实例来对此进行阐述。 0. 测试环境 OSWindows Server 2008 Enterprise sp1IDEVisual Studio 2008, …

【LeetCode - 33】搜索旋转排序数组(二分)

力扣 解题报告&#xff1a; 二分。但是有不少细节要考虑清楚。 所以干脆考虑另一种二分的方式。也就是第二次二分的时候&#xff0c;把两半数组给拼成一个完整的数组&#xff0c;当然下标需要是虚拟的&#xff0c;这一步可以用偏移量取模完成。这样就不需要考虑边界情况了。 …

【LeetCode - 1765】. 地图中的最高点

力扣 解题报告&#xff1a; 多元BFS。 进阶一下&#xff1a; 二维数组&#xff0c;1表示等高线&#xff0c;0表示平地&#xff0c;比如 输入 010 111 010 输出 010 121 010输入 010 101 010 输出 010 111 010即输入一个二维地图&#xff0c;保证等高线一定是闭合的环&#x…

【转】微服务架构下分布式事务方案

1 微服务的发展 微服务倡导将复杂的单体应用拆分为若干个功能简单、松耦合的服务&#xff0c;这样可以降低开发难度、增强扩展性、便于敏捷开发。当前被越来越多的开发者推崇&#xff0c;很多互联网行业巨头、开源社区等都开始了微服务的讨论和实践。Hailo有160个不同服务构成…

【LeetCode - 443】压缩字符串(模拟)

解题报告&#xff1a; 直接模拟。 class Solution { public:int compress(vector<char>& chars) {int p 0;for(int i 0; i<chars.size();) {int j i1;while(j<chars.size() && chars[j] chars[i]) j;chars[p] chars[i];if(j-i > 1) {int cnt…

Linq to SQL之使用事务

事务是一个原子的工作单位&#xff0c;必须完整的完成单位里的所有工作&#xff0c;要么全部执行&#xff0c;要么全部都不执行。如果提交事务&#xff0c;则事务执行成功&#xff1b;如果回滚事务&#xff0c;则事务执行失败。 事务具备4个基本特性--ACID(原子性、一致性、孤立…