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 ...
随机推荐
- nginx配置解决vue单页面打包文件大,首次加载慢的问题
cnpm run build 文件过大,其中主要是vender.js有1.5M,代码部署到服务器,首次访问加载页面时比较慢,耗时6.5s左右,所以需要优化下. 1.Nginx开启gzip 找到ngin ...
- C++ vector用法(转)
在c++中,vector是一个十分有用的容器,下面对这个容器做一下总结. 1 基本操作 (1)头文件#include<vector>. (2)创建vector对象,vector<in ...
- 【pyhon】理想论坛爬虫1.07 退出问题,乱码问题至此解决,只是目前速度上还是遗憾点
在 https://www.cnblogs.com/mengyu/p/6759671.html 的启示下,解决了乱码问题,在此向作者表示感谢. 至此,困扰我几天的乱码问题和退出问题都解决了,只是处理速 ...
- (算法)位图BitMap
题目: 给定一数组,大小为M,数组中的数字范围为1-N,如果某带宽有限,无法传输该大小的数组,该怎么办? 思路: 通过位图BitMap来压缩数组,将数组中每个数字在bit位上标志,这样就可以将数组大小 ...
- HDU 1199 && ZOJ 2301 线段树离散化
一段长度未知的线段.一种操作:a b c ,表示区间[a,b]涂为颜色C,w代表白色,b代表黑色,问终于的最长连续白色段,输出起始位置和终止位置 离散化处理.和寻常的离散化不同,须要把点化成线段.左闭 ...
- 算法笔记_206:第五届蓝桥杯软件类决赛真题(Java语言A组)
目录 1 海盗分金币 2 六角幻方 3 格子放鸡蛋 4 排列序数 5 幂一矩阵 6 供水设施 前言:以下代码仅供参考,若有错误欢迎指正哦~ 1 海盗分金币 有5个海盗,相约进行一次帆船比赛. 比 ...
- java之八大排序
的关系: 1.直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排 好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数 也是排好顺序的.如此反 ...
- wso2esb安装及helloworld
1.系统环境 Ubuntu12.04 192.168.0.97 root/password找管理员 Ubuntu12.04 192.168.0.99 root/password ...
- 【BIRT】在页面上展示xxxx年xx月xx日
我们在做报表开发的时候经常会遇到一个问题,就是需要在报表上展示”xxxx年xx月xx日”这种日期,例如:需要在报表展示日期如下图: 我们现在数据库存储的日期是:20171231 那么我们如何转化为 这 ...
- 推荐10 款 SVG 动画的 JavaScript 库
SVG 通常可以用作跨分辨率视频.这意味着在一块高分屏幕上不会降低图片的锐度.此外,你甚至可以让SVG动起来,通过使用一些javascript类库.下面,我们分享一些javascript类库,这些类库 ...