没想到《Linux Debugging:使用反汇编理解C++程序函数调用栈》发表了收到了大家的欢迎。但是有网友留言说不熟悉汇编,因此本书列了汇编的基础语法。这些对于我们平时的调试应该是够用了。
1 AT&T与Intel汇编语法对比
本科时候大家学的基本上都是Intel的8086汇编语言,微软采用的就是这种格式的汇编。GCC采用的是AT&T的汇编格式, 也叫GAS格式(Gnu ASembler GNU汇编器)。
1、寄存器命名不同
AT&T |
Intel |
说明 |
%eax |
eax |
Intel的不带百分号 |
2、操作数顺序不同
AT&T |
Intel |
说明 |
movl %eax, %ebx |
mov ebx, eax |
Intel的目的操作数在前,源操作数在后;AT&T相反 |
3、常数/立即数的格式不同
AT&T |
Intel |
说明 |
movl $_value,%ebx |
mov eax,_value |
Intel的立即数前面不带$符号 |
movl $0xd00d,%ebx |
mov ebx,0xd00d |
规则同样适用于16进制的立即数 |
4、操作数长度标识
AT&T |
Intel |
说明 |
movw %ax,%bx |
mov bx,ax |
Intel的汇编中, 操作数的长度并不通过指令符号来标识。
AT&T的格式中, 每个操作都有一个字符后缀, 表明操作数的大小. 例如:mov指令有三种形式:
movb 传送字节
movw 传送字
movl 传送双字
如果没有指定操作数长度的话,编译器将按照目标操作数的长度来设置。比如指令“mov %ax, %bx”,由于目标操作数bx的长度为word,那么编译器将把此指令等同于“movw %ax, %bx”。 |
5、寻址方式
AT&T |
Intel |
说明 |
imm32(basepointer,
indexpointer,
indexscale) |
[basepointer + indexpointer*indexscale + imm32) |
两种寻址的实际结果都应该是
imm32 + basepointer + indexpointer*indexscale |
例如: 下面是一些寻址的例子:
AT&T |
Intel |
说明 |
mov 4(%ebp), %eax |
mov eax, [ebp + 4] |
基址寻址(Base Pointer Addressing Mode),用于访问结构体成员比较方便,例如一个结构体的基地址保存在eax 寄存器中,其中一个成员在结构体内的偏移量是4字节,要把这个成员读上来就可以用这条指令 |
data_items(,%edi,4) |
[data_items+edi*4 |
变址寻址(Indexed Addressing Mode),访问数组 |
movl $addr, %eax |
mov eax, addr |
直接寻址(Direct Addressing Mode) |
movl (%eax), %ebx |
mov ebx, [eax] |
间接寻址(Indirect Addressing Mode),把eax 寄存器的值看作地址,把内存中这个地址处的32位数传送到ebx 寄存器 |
mov $12, %eax |
mov eax, 12 |
立即数寻址(Immediate Mode) |
mov $12, %eax |
mov eax, 12 |
寄存器寻址(Register Addressing Mode |
6.跳转方式不同
AT&T 汇编格式中,绝对转移和调用指令(jump/call)的操作数前要加上'*'作为前缀,而在 Intel 格式中则不需要。
AT&T |
Intel |
说明 |
jmp *%eax |
jmp %eax |
用寄存器%eax中的值作为跳转目标 |
jmp *(%eax) |
jmp (%eax) |
以%eax中的值作为读入的地址, 从存储器中读出跳转目标 |
2 求一个数组最大数
通过求一个数组的最大数,来进一步学习AT&T的语法
- #PURPOSE:Thisprogramfindsthemaximumnumberofa
- #setofdataitems.
- #
- #VARIABLES:Theregistershavethefollowinguses:
- #
- #%edi-Holdstheindexofthedataitembeingexamined
- #%ebx-Largestdataitemfound
- #%eax-Currentdataitem
- #
- #Thefollowingmemorylocationsareused:
- #
- #data_items-containstheitemdata.A0isused
- #toterminatethedata
- #
- .section.data#全局变量
- data_items:#Thesearethedataitems
- .long3,67,34,222,45,75,54,34,44,33,22,11,66,0
- .section.text
- .globl_start
- _start:
- movl$0,%edi#move0intotheindexregister
- movldata_items(,%edi,4),%eax#loadthefirstbyteofdata
- movl%eax,%ebx#sincethisisthefirstitem,%eaxis
- #thebiggest
- start_loop:#startloop
- cmpl$0,%eax#checktoseeifwe'vehittheend
- jeloop_exit
- incl%edi#loadnextvalue
- movldata_items(,%edi,4),%eax
- cmpl%ebx,%eax#comparevalues
- jlestart_loop#jumptoloopbeginningifthenew
- #oneisn'tbigger
- movl%eax,%ebx#movethevalueasthelargest
- jmpstart_loop#jumptoloopbeginning
- loop_exit:
- #%ebxisthestatuscodeforthe_exitsystemcall
- #anditalreadyhasthemaximumnumber
- movl$1,%eax#1isthe_exit()syscall
- int$0x80
汇编程序中以
.
开头的名称并不是指令的助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为汇编指示(Assembler Directive)或伪操作(Pseudo-operation),由于它不是真正的指令所以加个“
伪”字。
.section
指示把代码划分成若干个段(Section),程序被操作系统加载执行时,每个段被加载到不同的地址,操作系统对不同的页面设置不同的读、写、执行权限。
.data
段保存程序的数据,是可读可写的,相当于C++程序的全局变量。
.text
段保存代码,是只读和可执行的,后面那些指令都属于.text
段。
.long
指示声明一组数,每个数占32;.quad类似,占64位;.byte是8位;.word 是16位。.ascii
,例如.ascii "Hello world"
,声明11个数,取值为相应字符的ASCII码。
参考资料:
1.
最简单的汇编程序
2.
第二个汇编程序
3. http://blog.chinaunix.net/uid-27717694-id-3942757.html
最后复习一下lea命令:
mov 4(%ebp) %eax #将%ebp+4地址处所存的值,mov到%eax
leal 4(%ebp) %eax #将%ebp+4的地址值, mov到%eax
leal 可以被mov取代:
addl $4, %ebp
mov. %ebp, %eax
分享到:
相关推荐
6.跳轉方式不同 1. #PURPOSE: This program finds the maximum number of a 3. # 4. #VARIAB
Linux Debugging and Performance Tuning Tips and Techniques
Linux Debugging and Performance Tuning (Prentice, 2005)
详细的揭示了linux下的AT&T汇编指令使用方法,给出了各种汇编指令,指令用法,以及相应的例程。其中包括一些如何使用汇编链接C语言库,汇编调用系统调用,汇编执行浮点运算,C语言内嵌汇编等。 Chapter 1: What Is ...
Linux调试技术和性能调优手段,chm格式
Windows Debugging tool 32位和64位的都有,包括适用于windows7的和支持windows8的两种版本,安装好任意一种后,即可在QT Creator中使用CDB调试,当然也可以4种都安装!
Linux Debugging and Performance Tuning Tips and Techniques.rar
請下載本文用到的coredump: Linux Debugging: coredump 分析入門的材料Program received signal SIGSE
本文是http://blog.csdn.net/anzhsoft/article/details/18762915用到的例子。下载后先unzip,在tar xf
本文是http://blog.csdn.net/anzhsoft/article/details/18762915用到的例子。
如何使用trace32 调试linux 、android 调试环境组成 调试器设置 目标板设置 (bootloader scripts 等用于内核设置及引导) 调试器MMU的设置 启动TRACE32 Linux-Awareness 启动linux
format: chm. Doc for linux debuging and performance.
Linux Debugging(六): 動態庫注入、ltrace、strace、By anzhsoft | Published 2014年3月6日實際上,Lin
Andes N1013/N1033/N1068/N1233/N1337 Linux Debugging guide.
Linux - Linux Software Debugging With Gdb
1.背景-PICVSRelocatable在Linux 下製作動態鏈接庫,“標準” 的做法是編譯成位置無關代碼(那麼什麼是PIC呢?如果是非PIC的,那麼會有什
掌握内核调试方法,无疑是事半功被之举。调试是基本功之一
Advanced Apple Debugging & Reverse Engineering, Second Edition ISBN: Learn the powerful secrets of Apple’s software debugger, LLDB, that can get more information out of any program than you ever ...
Debugging Linux Systems was released in November 2009. This was created by filtering out portions related to debugging from ELDD, rendering the resulting work stand-alone, and upgrading the content to...