C语言代码内嵌汇编的方法:

在C语言文件中以如下格式加入汇编代码
__asm__(
“汇编语句模板”
:输出部分
:输入部分
:“破坏描述部分”
)
asm可以由__asm__代替,为其别名。
可加上__volatile__表示不需要编译器优化代码。
用双下划线起始或结尾。
所有汇编语句在双引号内,并以\n\t结束每一行。
$后跟立即数。
寄存器用%%+寄存器名表示:%%eax
参数用%+参数序号表示:%0 , %1 。。。
输入输出部分跟在语句后,用()表示,每一行前有“:”符号
参数序号与参数出现顺序一一对应。
参数前可以跟说明符,用“   ”表示,常用限定符意义如下
具体寄存器
a,b,c,d   将变量放入eXx
s  D      将变量放入esi   edi
q          将变量放入e(a,b,c,d)x中的任一个
r          将变量放入(a,b,c,d,s,d)中任一个
A         把eax和edx合成一个64的寄存器
 
内存
m        内存变量
o         内存变量,寻址方式是偏移量类型
V         内存变量,寻址方式不是偏移量类型
,        内存变量,寻址方式为自动增量
p         操作数是一个合法的内存地址
寄存器或内存
g         将输入变量放入eax,ebx,ecx,edx中的一个或作为内存变量
X         操作数为任何类型
立即数
I         0-31之间的立即数(用于32位移位指令)
J         0-63立即数(用于64)
N       0-255立即数(用于out指令)
i         立即数
n        立即数,对不支持数字以外立即数的系统使用
操作数类型
=       只写(输出)
+       读写类型(输入输出操作数)
浮点数
f        浮点数
t        第一个浮点寄存器
u       第二个浮点寄存器
G      标准的80387(指协处理器浮点运算部件80387)
%     该操作数可与下一个操作数交换位置
#      部分注释,从该字符到后面逗号之前的所有内容被忽略
\*     选用寄存器,则其后字母被忽略
匹配
“0”、“1”。。。“9”
表示被限制的操作数与某个指定的操作数匹配
以下面的程序为例讲一下应用:
 #include<stdio.h>
#include <unistd.h>
int main()
{
int a,b;
pid_t t,asm_t;
t =getpid();
a = t;
printf("pid = %d\n",a);
asm volatile(
"mov $0x14,%%eax\n\t"
"int $0x80\n\t"
"mov %%eax,%0\n\t"
:"=m"(asm_t)
);
b = asm_t;
printf("asm_t = %d\n",b);
return ;
}
程序里面用到了系统调用getpid。它的原型是:
pid_t getpid(void)
getpid的调用编号为20(0x14),所有系统调用的编号可以在unistd.h文件里找到。
发起系统调用的过程为:
  • 应用程序通过调用C语言函数库中的外壳函数(wrapper),发起系统调用
  • 外壳函数必须保证所有的系统调用参数可用,这些参数通过堆栈传入外壳函数,内核希望将这些参数置入通用寄存器。因此,外壳函数会将上述参数复制到寄存器,个数不超过6个(ebx,ecx,edx,esi,edi,ebp)每个参数长度不超过寄存器的位数--32位。
  • 为了 让内核能区分每个系统调用,外壳函数会将系统调用编号复制到特定的通用寄存器中-->%eax
  • 在此之后,外壳函数执行一条中断指令,引发用户态到核心态的切换,并执行系统中断0x80(128d)的中断矢量所指向的代码
  • 内核调用system_call以响应0x80中断,过程如下:
  1. 在内核栈中保存寄存器值
  2. 审核调用编号的有效性
  3. 以系统调用编号对存放所有调用服务程序的列表(sys_call_table)进行索引,查找并调用相应的系统调用服务程序。若服务程序需要参数,则检查参数的有效性。
  4. 从内核栈中恢复各寄存器值,将系统调用返回置于栈中。
  5. 返回至外壳函数,同时将处理器切换回用户态
  • 若系统调用的返回值表明调用有误,外壳函数会使用该值设置全局变量errno,无误则返回调用程序,并返回一个整型值,表明系统调用是否成功。
执行结果如下:

by 昆仑雪狐

原创作品转载请注明出处

《Linux内核分析》

MOOC课程http://mooc.study.163.com/course/USTC-1000029000

库函数API和C语言汇编语言混合式编程的更多相关文章

  1. 单片机C 语言与汇编语言混合编程

    在单片机应用系统设计中,过去主要采用汇编语言开发程序. 汇编语言编写的程序对单片机硬件操作很方便,编写的程序代码短,效率高,但系统设计的周期长,可读性和可移植性都很差.C语言程序开发是近年来单片机系统 ...

  2. 通过库函数API和C代码中嵌入汇编代码剖析系统调用的工作机制

    作者:吴乐 山东师范大学<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 本次实验的主要内容就是分别采用A ...

  3. 实验--使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用(杨光)

    使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 攥写人:杨光  学号:20135233 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程 ...

  4. C语言之基本编程思想与基本概念扫盲

    前言:C语言是包含了很多编程的基本思想,理解C能够有助于理解其他高级语言,深刻理解编程很多基本思想:这对新手入门是有很多好处的,正所谓磨刀不误砍柴工,内功与基础修炼扎实了,才能开始盖高楼大厦. 这篇文 ...

  5. linux内核分析作业4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    系统调用:库函数封装了系统调用,通过库函数和系统调用打交道 用户态:低级别执行状态,代码的掌控范围会受到限制. 内核态:高执行级别,代码可移植性特权指令,访问任意物理地址 为什么划分级别:如果全部特权 ...

  6. 【算法】C语言趣味程序设计编程百例精解

    C语言趣味程序设计编程百例精解 C/C++语言经典.实用.趣味程序设计编程百例精解(1)  https://wenku.baidu.com/view/b9f683c08bd63186bcebbc3c. ...

  7. 【转】VxWorks中高精度实时时钟的实现及C语言汇编混合编程

    最近一个项目中需要在VxWorks下使用一个高精度实时时钟,要求精度为1ms,溢 出时间大于5小时.VxWorks提供系统时钟,该时钟在操作系统启动后开始计数,精度为1个tick,可以通过tickGe ...

  8. LInux内核分析--使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    实验者:江军 ID:fuchen1994 实验描述: 选择一个系统调用(13号系统调用time除外),系统调用列表参见http://codelab.shiyanlou.com/xref/linux-3 ...

  9. 实验四——使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    实验目的: 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 实验过程: 查看系统调用列表 get pid 函数 #include <stdio.h> #include & ...

随机推荐

  1. YY前端课程3

    1. 常用的字符实体(html实体):空格=      <=<       >=>       版权符号=© 2. ID就像身份证号一样,是唯一的,html页面的ID不能重复: ...

  2. GitHub的使用之新建与更新代码

    一.新建仓储:注册GitHub后你就会有0.3G的免费空间,不过只能创建公开项目,这也满足代码分享的目的,我最喜欢的倒是它的代码展示方式,可以直接浏览你的代码,代码是经过高亮.添加行号处理过的,十分漂 ...

  3. Python函数参数学习笔记

    1.Python中函数参数类型可分为五种: f(x):x为位置参数: f(x,n=2):n为默认参数,调用时可以省略参数n,如f(5); f(*args):*args表示把args这个list或tup ...

  4. 使用C++11的一点总结

          C++11已不是新鲜技术,但对于我来说,工作中用得还不够多(前东家长时间使用gcc3.4.5,虽然去年升了4.8.2,但旧模块维护还是3.4.5居多:新东家用的是4.4.6,不能完整支持C ...

  5. 简化通过classname查找 方法

    function getClass(oParent,sclass){ var aEle=oParent.getElementsByTagName('*'); var result=[]; for(va ...

  6. How to Develop blade and soul Skills

    How to Develop Skills Each skill can be improved for variation effects. Some will boost more strengt ...

  7. LeetCode Spiral Matrix

    class Solution { public: vector<int> spiralOrder(vector<vector<int> > &matrix) ...

  8. linux桌面的安装

    在CentOS 7中提供了两种桌面"GNOME DESKTOP" 和 "KDE Plasa Workspaces",我们以安装"GNOME DESKT ...

  9. win7 64位4GB内存下 tomcat7扩大内存

    新部署的scm项目运行第二天报: Could not retrieve transation read-only status server 无法获取事务只读状态服务器 登录界面输入正确账号密码登录后 ...

  10. 编译内核实现iptables防火墙layer7应用层过滤 (三)

    在前面的两篇文章中我们主要讲解了Linux防火墙iptables的原理及配置规则,想博友们也都知道iptables防火墙是工作在网络层,针对TCP/IP数据包实施过滤和限制,属于典型的包过滤防火墙.以 ...