X86 寻址方式、AT&T 汇编语言相关知识、AT&T 与 Intel 汇编语言的比较、gcc 嵌入式汇编
注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早,分析的版本为2.4.16,故出现的一些概念可能跟最新版本内核不同。
此书已经开源,阅读地址 http://www.kerneltravel.net
set 即指令集,比如x86, PowerPC,
ARM等平台的指令集是不同的。而汇编一直存在两种不同的语法,在intel的官方文档中使用intel语法,Windows也使用intel语法,而UNIX
系统的汇编器一直使用AT&T语法,下文会比较两种语法的区别。
指令可以把一个立即数传送到eax 中,也可传送到ebx 中。但也有一些指令规定只能用其中某个寄存器做某种用途,例如除法指令idivl
要求被除数在eax 寄存器中,edx 寄存器必须是0,而除数可以在任意寄存器中,计算结果的商数保存在eax
寄存器中(覆盖原来的被除数),余数保存在edx 寄存器中。也就是说,通用寄存器对于某些特殊指令来说也不是通用的。
ADDRESS_OR_OFFSET(%BASE_OR_OFFSET,%INDEX,MULTIPLIER)
address
也只是逻辑地址中的32位偏移量部分,需要使用段选择符找到段描述符,进而得到段基地址,两者相加才是线性地址,但在Linux实现中段基地址都为0,故偏移量可以直接当作线性地址,再经过分页转换就是真正的物理地址,也就是说final
address 是程序中访问的地址。具体参见 《80386分段分页机制》
在有些寻址方式中会省略这4项中的某些项,相当于这些项是0。
,把eax 寄存器的值看作地址,把内存中这个地址处的32位数传送到ebx 寄存器。注意和movl %eax, %ebx 区分开。
Mode)。只使用ADDRESS_OR_OFFSET和BASE_OR_OFFSET寻址,例如movl 4(%eax), %ebx
,用于访问结构体成员比较方便,例如一个结构体的基地址保存在eax
寄存器中,其中一个成员在结构体内的偏移量是4字节,要把这个成员读上来就可以用这条指令。
,这跟内存寻址没什么关系,但也算作一种寻址方式。在汇编程序中寄存器用助记符来表示,在机器指令中则要用几个Bit表示寄存器的编号,这几个Bit也可以看作寄存器的地址,但是和内存地址不在一个地址空间。
二、AT&T 与 Intel 汇编语言的比较
中,十六进制立即数前冠以“0x”,如表2.2 所示给出几个相应的例子。
的语法符合人们通常的阅读习惯。
.png)
全部是可选的,完全可以简化掉。如果没有指定scale 而指定了index,则scale 的缺省值为1。segreg 段寄存器依赖于指令以及应用程序是运行在实模式还是保护模式下,在实模式下,它依赖于指令,而在保护模式下,segreg 是多余的。在AT&T
中,当立即数用在scale/disp 中时,不应当在其前冠以“$”前缀,表2.3 给出其语法及几个相应的例子。
.png)
为数组的起始地址,scale 为每个数组元素的大小,index 为下标。如果数组元素还是一个结构,则disp 为具体字段在结构中的位移。
的语法中,则要在内存单元操作数的前面加上byte ptr、word ptr 和dword ptr,“dword”对应“long”。表2.4 给出了几个相应的例子。
的C 编译器gcc,就可以一步完成汇编和连接,例如:
等,也就是说,使用gcc 进行编译,你可以在汇编程序中使用C 的预处理命令。
hello: .string "Hello world!\n"hello_len : .long 13
name : .fill 30 # 用来请求用户输入名字name_len : .long 0 # 名字的长度(尚未定义)
比使用.data 的优势在于,.bss 节不占用磁盘的空间。在磁盘上,一个长整数就足以存放.bss 节。当程序被装入到内存时,操作系统也只分配给这个节4 个字节的内存大小。
中的代码为例)。
.asciz "Unknown interrupt\n"
个字节以8 个为一组,每组的最高4 个字节内容为0,最低4 字节内容置为value。size 和 value 为可选项。如果第2 个逗号和value 值不存在,则假定value 为0。如果第1 个逗号和size 不存在,则假定size 为1。
.globl SYMBOL_NAME(idt).globl SYMBOL_NAME(gdt)
.quad 0x00cf9a000000ffff /* 0x10 kernel 4GB code at 0x00000000 */.quad 0x00cf92000000ffff /* 0x18 kernel 4GB data at 0x00000000 */.quad 0x00cffa000000ffff /* 0x23 user 4GB code at 0x00000000 */.quad 0x00cff2000000ffff /* 0x2b user 4GB data at 0x00000000 */
.rept 3.long 0.endr
.long 0.long 0.long 0
.space 1024
.word GDT_ENTRIES*8-1
是个错误的值,则.org 被忽略。.org 只能增加位置计数器的值,或者让其保持不变;但绝不能用.org 来让位置计数器倒退。
|
1
2 3 4 5 6 7 |
#define read_cr0() ({ \
unsigned int __dummy; \ __asm__( \ "movl %%cr0,%0\n\t" \ :"=r" (__dummy)); \ __dummy; \ }) |
可以有8 个。指令中有几个操作数,就说明有几个变量需要与寄存器结合,由gcc 在编译时根据后面输出部分和输入部分的约束条件进行相应的处理。由于这些样板操作数的前缀使用了“%”,因此,在用到具体的寄存器时就在前面加两个“%”,如%%cr0。
.png)
中的宏定义__cli():
|
1
|
#define __cli() __asm__ __volatile__("cli": : :"memory")
|
|
1
2 3 |
#define __save_flags(x) __asm__ __volatile__("pushfl ; popl %0":"=g"(x): /* no input*/)
#define __restore_flags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */:"g"(x):"memory", "cc") |
个宏。
|
1
2 3 4 5 6 7 |
static inline unsigned long get_limit(unsigned long segment)
{ unsigned long __limit; __asm__("lsll %1,%0" :"=r" (__limit) :"r" (segment)); return __limit + 1; } |
结合),函数返回__limit 加1,即段长。
中。
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
static inline int strcmp(const char *cs, const char *ct)
{ int d0, d1; register int __res; __asm__ __volatile__( "1:\tlodsb\n\t" "scasb\n\t" "jne 2f\n\t" "testb %%al,%%al\n\t" "jne 1b\n\t" "xorl %%eax,%%eax\n\t" "jmp 3f\n" "2:\tsbbl %%eax,%%eax\n\t" "orb $1,%%al\n" "3:" :"=a"(__res), "=&S" (d0), "=&D"(d1) :"1"(cs), "2"(ct)); return __res; } |
|
1
2 3 4 5 6 7 8 9 10 |
1: lodsb //装入串操作数,即从[esi]传送到al 寄存器,然后esi 指向串中下一个元素
scasb //扫描串操作数,即从al 中减去[edi],不保留结果,只改变标志 jne 2f //如果两个字符不相等,则转到标号2 testb %al %al jne 1b xorl %eax %eax jmp 3f 2: sbbl %eax %eax orb $1 %al 3: |
X86 寻址方式、AT&T 汇编语言相关知识、AT&T 与 Intel 汇编语言的比较、gcc 嵌入式汇编的更多相关文章
- OpenCV&Qt学习之四——OpenCV 实现人脸检测与相关知识整理
开发配置 OpenCV的例程中已经带有了人脸检测的例程,位置在:OpenCV\samples\facedetect.cpp文件,OpenCV的安装与这个例子的测试可以参考我之前的博文Linux 下编译 ...
- PySpark SQL 相关知识介绍
title: PySpark SQL 相关知识介绍 summary: 关键词:大数据 Hadoop Hive Pig Kafka Spark PySpark SQL 集群管理器 PostgreSQL ...
- C语言相关知识
1.指针:在程序中定义了一个变量,在进行编译时就会给该变量再内存中分配一个地址,通过访问这个地址可以找到所需变量,这个变量的地址成为该变量的指针.指针看作是内存中的一个地址,多数情况下,这个地址是内存 ...
- 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸
类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...
- 移动WEB像素相关知识
了解移动web像素的知识,主要是为了切图时心中有数.本文主要围绕一个问题:怎样根据设备厂商提供的屏幕尺寸和物理像素得到我们切图需要的逻辑像素?围绕这个问题以iphone5为例讲解涉及到的web像素相关 ...
- listener监听器的相关知识
从别人的博客上我学习了listener的相关知识现在分享给大家 1.概念: 监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上 ...
- UIViewController相关知识
title: UIViewController 相关知识date: 2015-12-13 11:50categories: IOS tags: UIViewController 小小程序猿我的博客:h ...
- 【转】java NIO 相关知识
原文地址:http://www.iteye.com/magazines/132-Java-NIO Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的 ...
- NSString使用stringWithFormat拼接的相关知识
NSString使用stringWithFormat拼接的相关知识 保留2位小数点 1 2 3 4 //.2代表小数点后面保留2位(2代表保留的数量) NSString *string = [NSSt ...
随机推荐
- NSURLSession下载和断点续传
NSURLSession是iOS7之后新的网络接口,和经常用到NSURLConnection是类似的.在程序在前台时,NSURLSession与NSURLConnection可以相互的替代.但是当用户 ...
- Win10系统下软件UI显示不完整解决方案
在最初升级win10的时候就想到了这些问题,例如和各种软件的不兼容性.当然,事实上win10并没有想象的那么糟,作为一个windows user 来说,win10的确是很高大上的,无论是颜值或者是体验 ...
- Windows 8提升普通管理员权限为超级管理员权限以及激活超级管理员Administrator
在Windows 8下运行某些操作时(比如删除一些文件或者更改某些系统设置时)系统会提示我们权限不够.须要Administrator账户的权限. 相信很多其它的使用者都会觉得自己当前使用的账户已经是系 ...
- ArcGIS中的批量处理
在实际生产过程中,经常遇到批量处理数据的情况.在ArcGIS中,除自己写代码来处理这类问题外,它提供了一个批量处理的工具,在ToolBox对应的工具上右键即可选择批处理工具. 和单个处理方式一样,输入 ...
- BIOS和Bootloader的对比
桌面电脑刚加电时,一个叫做BIOS的软件程序立刻获得了处理器的控制权.(历史上,BIOS是Basic Input/Output Software的缩写,但现在这个单词已经有了自身的含义,因为其完成的功 ...
- YUM常用命令详解
yum是一个用于管理rpm包的后台程序,用python写成,可以非常方便的解决rpm的依赖关系.在建立好yum服务器后,yum客户端可以通过 http.ftp方式获得软件包,并使用方便的命令直接管理. ...
- Jacoco的原理(各个覆盖率的解释)
覆盖率计数器 Jacoco使用一系列的不同的计数器来做覆盖率的度量计算.所有这些计数器都是从java的class文件中获取信息,这些class文件可以(可选)包含调试的信息在里面.即使在没有源码的情况 ...
- line-height测量及使用
1.line-height定义 line-height表示行高,即两行文字基线间的距离. 以下是图示说明: 行高是2条红线之间的距离,即:1+2+3+4 在实际测量中,基线不好找,可测量顶线到顶线的距 ...
- ci高级使用方法篇之连接多个数据库
在我们的项目中有时可能须要连接不止一个数据库.在ci中怎样实现呢? 我们在本地新建了两个数据库,例如以下截图所看到的: 改动配置文件database.php文件为例如以下格式(读者依据自己数据库的情况 ...
- maven Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4
maven Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4 CreateTime--201 ...