通用寄存器:当处理器处理数据时,通用寄存器用于临时存放数据。
EAX:用于操作数和结果数据的累加器
EBX:指向数据内存段中的数据的指针
ECX:字符串和循环操作的计数器
EDX:I/O指针
EDI:用于字符串操作的目标的数据指针
ESI:用于字符串操作的源的数据指针
ESP:堆栈指针
EBP:堆栈数据指针
段寄存器:专门用于引用内存位置
平坦内存模式:把全部系统内存表示为连续的地址空间
分段内存模式:把系统内存划分为独立段的组。
实地址模式
CS:代码段
DS:数据段
SS:堆栈段
ES:附加段指针
FS:附加段指针
GS:附加段指针
指令指针寄存器:EIP寄存器、又称“程序计数器”,指令指针指向要执行的下一条指令。
控制寄存器:五个控制寄存器用于确定处理器的操作模式、与当前正在执行的任务特性。不能直接访问控制寄存器中的值,但可以把控制寄存器包含的数据传送给通用寄存器。
CR0控制操作模式和处理器状态的系统标志
CR1当前没有使用
CR2内存页面错误信息
CR3内存页面目录信息
CR4支持处理器特性和说明处理器特性能力的标志。
标志:用来确定程序功能是否成功执行的唯一途径。
状态标志:用来表明处理器进行的数学操作的结果。
标志
位
名称
CF
0
进位标志
PF
2
奇偶校验标志
AF
4
辅助进位标志
ZF
6
零标志
SF
7
符号标志
OF
11
溢出标志
控制标志:用于控制处理器的特定行为,控制标志——DF标志、即方向标志,用于控制处理器处理字符串的方式。
当DF标志被设置1时,字符串指令自动递减内存地址以便到达字符串的下一个字节; 当DF=0时,。。。递增。。。
系统标志:用于控制操作系统级别的操作
标志
位
名称
TF
8
陷阱标志
IF
9
中断使能标志
IOPL
12和13
I/O特权级别标志
NT
14
嵌套任务标志
RF
16
恢复标志
VM
17
虚拟8086模式标志
AC
18
对准检查标志
VIF
19
虚拟终端标志
VIP
20
虚拟中断挂起标志
ID
21
识别标志
x87浮点单元(简称FPU)
FPU寄存器
描述
数据寄存器
用于浮点数数据的8个80位寄存器
状态寄存器
报告FPU状态的16位寄存器
控制寄存器
控制FPU精度的16位寄存器
标志寄存器
描述8个数据寄存器的内容的16位寄存器
FIP寄存器
指向下一条FPU指令的48位FPU指令指针
FDP寄存器
指向内存中的数据的48位FPU数据指针
操作码寄存器
保存FPU处理的最后指令的11位寄存器
多媒体扩展(简称MMX)
单指令多数据(SIMD):SIMD模型使用扩展的寄存器长度和新的数字格式来加快实施多媒体表现所需的复杂数字处理
流化SIMD扩展(SSE)
二. 相关的工具
汇编器:把汇编语言源代码转化为处理器的指令码
汇编语言源代码程序有三部分:
操作码助记符
数据段
命令
汇编器之间最大的区别是汇编命令
MASM
NASM
gas(一个独特特性是能够创建不同于程序设计所在平台的平台的指令码,缺陷是不能在宿主系统上测试生成的程序)
HLA(高级汇编器)
连接器:链接目标代码的过程设计到解析程序代码中声明的所有定义好的函数和内存地址标签
调试器大多数调试器提供的基本功能:
在一个受控制的环境下运行程序,指定任何必须的运行时参数。
在程序内的任何位置停止程序。
检查数据元素,比如内存位置和寄存器
在程序运行时改变程序中的元素以便帮助消除缺陷。
编译器的工作是把高级语言转化为处理器能够执行的指令码。
目标代码反汇编器
简档器:能够跟踪每个函数在执行过程中被使用时花费了多长处理器时间。
GNU汇编器(gas),具有为以下几种不同硬件平台汇编指令码的能力:
VAX
AMD 29K
Hitachi H8/300
Intel 80960
M680x0
SPARC
Intel 80x86
Z8000
MIPS
安装汇编器(在binutils包内)
包
描述
add2line
把地址转换为文件名和行号
ar
创建、修改和展开文件存档
as
把汇编语言代码汇编为目标代码
c++filt
还原C++符号的过滤器
gprof
显示程序简档信息的程序
ld
把目标代码文件转换为可执行文件的连接器
nlmconv
把目标代码转换为Netware Loadable Module格式
objcopy
复制和翻译目标文件
ranlib
生成存档文件内容的索引
readelf
按照ELF格式显示来自目标文件的信息
size
列出目标文件或者存档文件的段长度
strings
显示目标文件中的可打印字符串
strp
丢弃符号
windres
编译Microsoft Windows资源文件
nm
列出目标文件的符号
objdump
显示来自目标文件的信息
安装binutils包
rpm: rpm -qa | grep binutils
deb: dpkg -l | grep binutils
使用汇编器gas,命令行可执行程序:as
as命令行参数:
参数
描述
-a
指定输出中包含哪些清单
-D
包含它用于向下兼容,但是被忽略
--defsym
在汇编源代码之前定义符号和值
-f
快速汇编,跳过注释和空白
--gstabs
包含每行源代码的调试信息
--gstabs+
包含专门的gdb调试信息
-I
指定搜索包含文件的目录
-J
不警告带符号溢出
-K
包含它用于向下兼容,但是被忽略
-L
在符号表中保存本地符号
--listing-lhs-width
设置输出数据列的最大宽度
--listing-lhs-width2
设置连续行的输出数据列的最大宽度
--listing-rhs-width
设置输出源代码的最大宽度
--listing-cont-lines
设置输出的单一行在清单中输出的最大行数
-o
指定输出目标文件的名称
-R
把数据段合并进文本段
--statistics
显示汇编使用的最大空间和总时间
-v
显示as的版本号
-W
不显示警告信息
--
对于原文件使用标准输入
操作码语法:Intel和AT&T语法区别
AT&T使用$表示立即操作数,而Intel的立即操作数是不需要界定的。
AT&T在寄存器名称前加上前缀%,而Intel无。在AT&T语法引用EAX寄存器写为%eax
AT&T语法处理源和目标操作数时使用相反的顺序。把十进制4传送给EAX寄存器,AT&T语法:mov1 $4, %eax ,而Intel语法是mov eax, 4
AT&T在助记符后面使用一个单独的字符来引用操作数中使用的数据长度,而Intel语法中数据长度被声明为单独的操作数。AT&T的指令mov1 $test, %eax 等同于Intel语法的mov eax, dword ptr test
长调用和跳转使用不同语法定义段和偏移值。AT&T语法使用jmp $section, $offset,而Intel语法使用jmp section:offset
GNU连接器ld用于把目标代码文件连接为可执行文件或者库文件。
GNU编译器,GNU编译器集合为gcc,参数详解
参数
描述
-c
编译或者汇编代码,但是不进行连接
-S
编译后停止,但是不进行汇编
-E
预处理后停止,但是不进行编译
-o
指定要使用的输出文件
-v
显示每个编译阶段使用的命令
-std
指定使用的语言标准
-g
生成调试信息
-pg
生成gprof制作简档要使用的额外代码
-O
优化可执行代码
-W
设置编译器警告信息级别
-pedantic
按照C标准发布强制性诊断清单
-I
指定包含文件的目录
-L
指定库文件的目录
-D
预定义源代码中的宏
-U
取消任何定义了的宏
-f
指定用于控制编译器行为的选项
-m
指定与硬件相关的选项
GNU调试器程序
gcc使用参数
参数
描述
-b
设置远程调试时串行接口的线路速度
-batch
以批处理模式运行
-c
指定要分析的核心转储文件
-cd
指定工作目录
-d
指定搜索源文件的目录
-e
指定要执行的目录
-f
调试时以标准格式输出文件名和行号
-nx
不执行.gdbinit文件的命令
-q
安静模式——不输出介绍
-s
指定符号的文件名
-se
指定符号和要执行的文件名
-tty
设置标准输入和输出设备
-x
从指定的文件执行gdb命令
在gdb命令提示下,调试命令:
命令
描述
break
在源代码中设置断点以便停止执行
watch
设置监视点,当变量到达特定值时停止执行
info
观察系统元素,比如寄存器、堆栈、内存
x
检查内存位置
print
显示变量值
run
在调试器内开始程序的执行
list
列出指定的函数或者行
next
执行程序中的下一条指令
step
执行程序中的下一条指令
cont
从停止的位置继续执行程序
until
运行程序,直到到达指定的源代码行
GNU objdump程序:可以查看显示汇编语言代码,而且能够显示生成的原始指令码。-d把目标代码反汇编为指令码
GNU简档器程序(gprof):用于分析程序的执行和确定应用程序中的“热点”在什么位置。“热点”是程序运行时需要最多处理时间的函数。一般为数学密集型的函数,但I/O密集型的函数也会增加处理时间。
输出格式参数
-p 不输出所有函数的一般简档,或者不显示指定函数的
-g
分析参数
杂项参数
三. 汇编语言程序范例
程序的组成
组成:
数据段:是在可执行程序内声明指令码的地方,数据段声明带有初值的数据元素
bss段:bss段声明使用零或者null值初始化的数据元素
文本段
定义段:GNU汇编器使用.section命令语句声明段。.section语句只使用一个参数——它声明段的类型。
bss段总是应该安排在文本段之前,数据段可以移到文本段之后,但不标准。因需易阅读,将所有数据定义集中在源代码的开头。
定义起始点:当汇编语言被转换为可执行文件时,连接器必须知道指令码的起始点是什么。对于使用分散在源代码各个位置的若干函数的更加复杂的程序。
GNU汇编器声明一个默认标签或称标识符,用作应用程序的入口点。
_start标签用作表明程序应从这条指令开始。若连接器找不到此标签,它会产生错误标签。
若连接器找不到_start标签,它会试图查找程序的起始点,但对于复杂的程序,不能保证连接器能正确地作出猜测。
可以使用_start之外的其他标签作为起始点。使用连接器的-e参数定义新的起始点的名称。
除在应用程序中声明起始标签之外,还需要为外部应用程序提供入口点。这里使用.globl命令完成。
.globl命令声明外部程序可以访问的程序标签。如果编写被外部汇编语言或者C语言程序使用的一组工具,就应该使用.globl命令声明每个函数段标签。
创建简单程序
CPUID指令是一条汇编指令,不容易从高级语言应用程序执行它。它是请求处理器的特定信息并且把信息返回到特定寄存器中的低级指令。
esc和cpcl是怎么区分
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
文件生成的ESC分隔符是怎么生成的 esc分隔符是怎么表示的
终于到(十)了~~~503页 ES:DI 指向未更新且未打开的FCB的指针 注释:该功能最初用来从命令行中析取文
文件生成的ESC分隔符是怎么生成的 寄存器 文件名 系统时间