汇编语言应用领域比较专业,较为晦涩难懂(好吧其实是很难,对开发者的计算机专业功底很高,融汇贯通了,开发个学术级的os内核不是问题了)。我学习汇编还是windows平台下做破解、脱壳、外挂、shellcode的那会儿。现在随着工作需要,基本上很少同windows打交道了,但是还是免不了同Linux下的汇编打交道,个人水平有限,大神可以忽略这篇文章了,看热闹的同学也可忽略了,因为看完了,你有可能还是什么都不懂,相反脑袋得被搞大了(^_^)。
Intel x86(IA-64) CPU架构下的汇编语言有两种语法风格(Intel汇编语言与AT&T汇编语言),8086与80386架构的汇编语言文档资料大多是Intel汇编语言风格的,Intel开发者手册中就是使用的这种风格的汇编语言(Windows下的当然就是Intel风格的啦)。AT&T的起源于UNIX息息相关,作为UNIX家族的重要一员,尽管Linux的历史不长,与其相关的很多事情都发源于Unix。
Linux所使用的386汇编语言而言,它也是起源于Unix。Unix最初是为PDP-11开发的,曾先后被移植到VAX及68000系列的处理器上,这些处理器上的汇编语言都采用的是AT&T的指令格式。当Unix被移植到i386时,自然也就采用了AT&T的汇编语言格式,而不是Intel的格式。
相对于java这类的高级语言,c语言经常被称作低级语言,这是因为c语言的应用场景比较偏向于底层,对os、cpu架构比较敏感,然而对于驱动开发或内核开发这样同硬件打交道的开发场景,c语言并不能够完全胜任,例如os引导区程序,初始化cr0、gdt等等寄存器,开启分页,分段的工作就必须依靠汇编语言来实现(汇编语言依赖于具体的cpu架构)。
gcc支持在c/c++中嵌入汇编代码,这对os开发、Linux驱动开发、Linux内核开发是不可或缺的功能。
gcc内联汇编的语法格式非常易懂,格式如下:
__asm__ [__volatile__]("instructions");
1、__asm__:这是一个对gcc关键字asm的宏定义,#define __asm__ asm,任何一处内联汇编代码,都应当以__asm__开头(asm关键字也可以定义内联汇编,但是如果编写符合ANSI C标准的代码,就应当以__asm__开头,内联汇编代码必须以__asm__宏或gcc关键字asm开头)。
2、__volatile__:gcc关键字volatile的宏定义,#define __volatile__ volatile,也是出于兼容ANSI C标准而定义的宏。方括号说明这个选项是可选的,它向gcc声明,保留每一条指令(对于volatile关键字的应用场景可以单独拿出一篇文章进行分析了),当你使用gcc的优化选项-O(-O/-O1/-O2/-O3/-Os)优化编译时,gcc会根据优化选项对代码做出优化。
3、instructions:汇编指令列表,当然你可以指定为空列表,例如__asm__ ("");或__asm__ __volatile__("");但这样做没有意义。当然也并非所有的空指令列表毫无意义,__asm__ __volatile__("":::memory);,可以告诉gcc这里的内存改变了。具体应用场景以后做详细阐述。
gcc内联汇编代码如下示例:
__asm__ __volatile__("mov $1, %eax;"); 立即寻址
__asm__ __volatile__("cld";); 清除DF位
__asm__ __volatile__("xor %eax, %eax"); 通用寄存器eax清零
__asm__ __volatile__("int $0x80;"); 调用80号中断(Linux系统用户态陷入内核态的中断号)
如果指令列表instructions中有多条指令,该怎么办?
这是我初次使用gcc内联汇编时,遇到的一个坑,特意贴出来同大家分享,避免大家犯这种低级错误。指令列表instructions中有多条指令,可以使用一对或多对双引号,每对双引号里面可以放入一条或多条指令,所有的指令都要放在双引号中,任意两条指令要么要被分号(;)要么被(\n)或者(\n\t)隔开。
示例代码如下:
1??形式一:
__asm__ __volatile__("mov $1, %eax\n\t"
"xor %ebx, %ebx\n\t"
"int $0x80");
或
__asm__ __volatile__("mov $1, %eax\n"
"xor %ebx, %ebx\n"
"int $0x80");
以上代码是用户态(RING3)程序陷入内核态(RING0)的标准的标准调用形式,(好吧,其实这个过程很复杂,Linux内核api就是以这种方式提供的,暂且不讨论这个,仅仅拿出来分析)。
2??形式二:
__asm__ __volatile__("mov $1, %eax;"
"xor %ebx, %ebx;"
"int $0x80");
阅读(1977) | 评论(0) | 转发(0) |