郑州信息科技中专职业学院中专部

不仅仅统招学历哟

  • 热门专业!
  • 大学校园!
  • 就业保障!
  • 拿学历又能高薪就业,谁能不爱!
了解详情>
郑州北大青鸟翔天信鸽参加“安心学习·放心就业”公约签约仪式

让每一个家庭“安心”、“放心”

  • 教学为本
  • 师爱为魂
  • 安心学习
  • 放心就业
了解详情>
北大青鸟20周年庆典与总部年会郑州翔天信鸽荣获7项荣誉

深耕细作IT职业教育15载

  • 青鸟之星教学质量大奖
  • 卓越风云人物
  • 北大青鸟中心理事会成员
  • 七项荣耀载誉而行!
了解详情>
郑州北大青鸟学员喜获全国IT精英挑战赛冠军

我们教学怎么样

  • 实力见证
  • 网络组一等奖
  • 网络组二等奖
  • 软件组四等奖
  • 200家校区脱颖而出!
了解更多>
北大青鸟荣获315重承诺守信用放心品牌

北大青鸟职业IT20周年

  • 重承诺
  • 守信用
  • 放心品牌
  • 放心学习
  • 靠靠谱谱好就业!
了解更多>
学IT好工作高薪就业

我命由我不由天

  • 学个性的技术
  • 做爱做的事
  • 挣满意的钱
  • 衣食无忧
  • 选择宽且高大尚!
了解更多>
郑州北大青鸟IT培训办学14年

我们靠不靠谱

  • 14年办学
  • 14年磨练
  • 14年成长
  • 14年探索
  • 只为让每个学员成材!
了解更多>
郑州北大青鸟IT培训

不打工也牛掰

  • 好工作
  • 好环境
  • 高薪资
  • 好课程
  • 支持你成为有“钱”人!
了解更多>

学IT就读北大青鸟

  • 好工作
  • 好未来
  • 好老师
  • 好课程
  • 支持你成为受人尊敬的人!
了解更多>
河南北大青鸟电脑培训:Linux GCC内嵌汇编基础知识
作者: 添加时间:10-13 浏览次数:0

 河南北大青鸟电脑培训,专业的电脑IT培训学校,今天我们给大家分享的是Linux GCC内嵌汇编基础知识。

在Linux代码中很多地方都使用了这种形式的汇编语言,嵌入汇编程序的格式如下:
  __asm__ __volatile__ (
  asm statements
  : outputs
  : inputs
  : registers-modified
  );
  asm statements是一组AT&T格式的汇编语言语句,每个语句一行,由\n分隔各行。所有的语句都被包裹在一对双引号内。其中使用的寄存器前面要加两个%%做前缀(%n表示参数,n:数字);转移指令多是局部转移,因此多使用数字标号。
  inputs指明程序的输入参数,每个输入参数都括在一对圆括号内,各参数用逗号分开。每个参数前加一个用双引号括起来的标志,告诉编译器把该参数装入到何处。
  可用的标志有:
  “g”:让编译器决定如何装入它;
  “a”:装入到ax/eax;
  “b”:装入到bx/ebx;
  “c”:装入到cx/ecx;
  “d”:装入到dx/edx;
  “D”:装入到di/edi;
  “S”:装入到si/esi;
  “q”:a、b、c、d寄存器等;
  “r”:任一通用寄存器;
  “i”:整立即数;
  “I”:0-31 之间的立即数(用于32位移位指令);
  “J”:0-63 之间的立即数(用于64 位移位指令);
  “N”:0-255 ,之间的立即数(用于out 指令);
  “n”:立即数,有些系统不支持除字以外的立即数,这些系统应该使用“n”而不是“i”;
  “p”:有效内存地址;
  “m”:内存变量;
  “o”:操作数为内存变量,但是其寻址方式是偏移量类型,也即是基址寻址,或者是基址加变址寻址;
  “V”:操作数为内存变量,但寻址方式不是偏移量类型;
  “,”:操作数为内存变量,但寻址方式为自动增量;
  “X”:操作数可以是任何类型;
  “f”:浮点数;
  “t”:第一个浮点寄存器;
  “u”:第二个浮点寄存器;
  “G”:标准的80387;
  %  :浮点常数,该操作数可以和下一个操作数交换位置;
  “=”:输出;
  “+”:既是输入又是输出;
  “&”:改变其值之前写,分配一个独立的寄存器,使得函数返回值和该变量不因为重复使用同一个寄存器,出现数据覆盖.
  “%”:与下一个操作数之间可互换;
  “#”:忽略其后的字符,直到逗号;
  “*”:当优先选择寄存器时,忽略下面的字符;
  “0”~“9”:指定一个操作数,它既做输入又做输出。通常用“g”;
  outputs指明程序的输出位置,通常是变量。每个输出变量都括在一对圆括号内,各个输出变量间用逗号隔开。每个输出变量前加一个标志,告诉编译器从何处输出。
  可用的标志与输入参数用的标志相同,只是前面加“=”。如“=g”。输出操作数必须是左值,而且必须是只写的。如果一个操作数即做输出又做输入,那么必须将它们分开:一个只写操作数,一个输入操作数。输入操作数前加一个数字限制(0~9),指出输出操作数的序号,告诉编译器它们必须在同一个物理位置。两个操作数可以是同一个表达式,也可以是不同的表达式。
  registers-modified告诉编译器程序中将要修改的寄存器。每个寄存器都用双引号括起来,并用逗号隔开。如“ax”。如果汇编程序中引用了某个特定的硬件寄存器,就应该在此处列出这些寄存器,以告诉编译器这些寄存器的值被改变了。如果汇编程序中用某种不可预测的方式修改了内存,应该在此处加上“memory”。这样以来,在整个汇编程序中,编译器就不会把它的值缓存在寄存器中了。
  如:
  “cc”:你使用的指令会改变CPU的条件寄存器cc;
  “memory”:你使用的指令会修改内存;
  __volatile__是可选的,它防止编译器修改该段汇编语句(重排序、重组、删除等)。
  输入参数和输出变量按顺序编号,先输出后输入,编号从0开始。程序中用编号代表输入参数和输出变量(加%做前缀)。
  输入、输出、寄存器部分都可有可无。如有,顺序不能变;如无,应保留“:”,除非不引起二意性。
  看一个在C语言中使用at&t的嵌入汇编程序的例子,c语言中的3个int变量,一般会是三个内存地址。每个操作数的长度则要根据操作系统和编译器来决定,一般32位操作系统为32位,则每个操作数占用4个字节:
  int i=0, j=1, k=0;
  __asm__ __volatile__("
  pushl %%eax\n //asm statement
  movl %1, %%eax\n //asm statement
  addl %2, %%eax\n //asm statement
  movl %%eax, %0\n //...
  popl %%eax" //...
  : "=g" (k) //outputs
  : "g" (i), "g" (j) //inputs
  : "ax", "memory" //registers modified
  );
  按照参数编号原则输出参数参数k为%0,输入参数i和j依次为%1和%2。值得注意的是输出和输入标志都使用了"g",所以我们不必关心这些参数究竟是使用了寄存器还是内存操作数,编译器自己会决定。

     以上就是Linux GCC内嵌汇编常用的基础知识,想要了解更多的网络技术知识请查看:http://www.hnbenet.com/  

本文源自:http://www.hnbenet.com 转载请注明出处!


本文由站河南北大青鸟校区整编而成,如需了解更多IT资讯类的文章、新闻、课程和学习技巧、就业案例、招生详情等问题,可以对在线咨询老师进行一对一问答!


分享到: