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. 网站整站下载工具—HTTrack Website Copier

    HTTrack是一个免费和易用的离线浏览工具(浏览器),它可以允许你下载整个WWW网站至本地目录,并且通过遍历网站目录获取HTML,图片和其他文件,是安全渗透测试和居家旅行必备软件. WinHTTra ...

  2. file_put_contents保存数据,

    file_put_contents("sui.txt", var_export($now_member,TRUE),FILE_APPEND); 可以保存数组,方便调试

  3. 【IE6双倍边距】-IE6双倍边距的bug

    效果 代码 CSS IE6双倍边距的bug body { margin: 0; padding: 0; } .div1 { width: 200px; height: 200px; backgroun ...

  4. 关于/usr/local/lib/libz.a(zutil.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC解决办法

    具体报错截图如下: 解决方法: 题外话,我对makefill cmake也是一窍不通因此本人也是不想去积极的解决这个问题,但是当你求助无缘的时候你才会静心去思考.读到这句话的时候也许你已经发现了问题所 ...

  5. Scala 并发编程

    Runnable/Callable 线程 Executors/ExecutorService Futures 线程安全问题 例子:搜索引擎 解决方案 Runnable/Callable Runnabl ...

  6. nginx 页面乱码问题

    在配置nginx时常常遇到网页乱码的问题如图: 这时需要在server段里面添加两行: default_type 'text/html'; charset utf-8; 然后执行测试  重启操作 ng ...

  7. javascript base64 字符转换

    function Base64() { // private property _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr ...

  8. gradle环境配置、

    话不多说,直接上流程. 1.下载 gradle.zip文件,我以为已经为大家准备好了各个版本的下载地址. 链接: http://pan.baidu.com/s/1hqjIVlE 密码: 8ccb 本人 ...

  9. Android ShapeDrawable

    今天做项目碰到一个这样的情况,就是颜色指示框,用的是正方形边框是黑色的,里面填充颜色,颜色值是动态的,为了解决这个问题,查了好多资料,终于找到解决的方法,利用ShapeDrawable,我们自定义一个 ...

  10. Python学习基本

    刚开始学习是看了这个网站: 廖雪峰的官方网站  http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac92707 ...