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 ...
随机推荐
- Sort Colors leetcode java
题目: Given an array with n objects colored red, white or blue, sort them so that objects of the same ...
- 巧妙利用jQuery和PHP打造类似360安全卫士防火墙功能开关(类似iphone界面)效果
安全卫士防火墙开启关闭的开关,可以将此功能应用在产品功能的开启和关闭功能上. 准备工作为了更好的演示本例,我们需要一个数据表,记录需要的功能说明及开启状态,表结构如下: CREATE TABLE `p ...
- xUtils如何通过注解对FindViewById进行封装
之前讲到了介绍了一下xUtils的基本使用方法,今天我们就来详细介绍一下关于xUtils中的ViewUtils模块. 在ViewUtils模块中我们首先看到的是它采用了一种注解的方式进行声明,那么我们 ...
- Pinger2
import java.io.IOException;import java.io.InputStreamReader;import java.io.LineNumberReader;import j ...
- HDU 4902 Nice boat 成段线段树
操作1 的时候标记deng[rt]表示以下一段数都是与当前节点的值同样 下次操作2时直接对有deng标记的节点gcd更新 (可能还能够更简单) #include <stdio.h> #in ...
- 算法笔记_185:历届试题 格子刷油漆(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如下图所示),现需要把这些格子刷上保护漆. 你可以从任意一个格子刷起,刷完一格,可 ...
- 第14章1节《MonkeyRunner源代码剖析》 HierarchyViewer实现原理-面向控件编程VS面向坐标编程
到此为止我们描写叙述的MonkeyRunner相应用的点击拖放等操作都是直接通过指定坐标点来实现的.比方以下触摸一个坐标点为(60,90)的按钮的脚本样例: 1 device.touch(60,900 ...
- crontab 格式
- XMPP serverejabberd-14.12本地搭建
这里记录下我搭建ejabberd-14.12的过程. 首先下载:http://pan.baidu.com/s/1hqzjezq 这里我传到我的网盘一份, 大家也能够到官网下载http://xmpp. ...
- from会存在潜在的陷阱
# -*- coding: utf-8 -*- #python 27 #xiaodeng #from会存在潜在的陷阱 #from时,可能会遇到相同变量名,变量会被悄悄覆盖掉, #但是import语句不 ...