LINUX汇编语言 GUN AS CHAPTER1
- 格式:pdf
- 大小:142.25 KB
- 文档页数:22
二、Linux 汇编语法格式绝大多数 Linux 程序员以前只接触过DOS/Windows 下的汇编语言,这些汇编代码都是 Intel 风格的。
但在 Unix 和 Linux 系统中,更多采用的还是 AT&T 格式,两者在语法格式上有着很大的不同:1.在 AT&T 汇编格式中,寄存器名要加上 '%' 作为前缀;而在 Intel 汇编格式中,寄存器名不需要加前缀。
例如:2.在 AT&T 汇编格式中,用 '$' 前缀表示一个立即操作数;而在 Intel 汇编格式中,立即数的表示不用带任何前缀。
例如:3.AT&T 和 Intel 格式中的源操作数和目标操作数的位置正好相反。
在Intel 汇编格式中,目标操作数在源操作数的左边;而在 AT&T 汇编格式中,目标操作数在源操作数的右边。
例如:4.在 AT&T 汇编格式中,操作数的字长由操作符的最后一个字母决定,后缀'b'、'w'、'l'分别表示操作数为字节(byte,8 比特)、字(word,16 比特)和长字(long,32比特);而在 Intel 汇编格式中,操作数的字长是用 "byte ptr" 和 "word ptr" 等前缀来表示的。
例如:5.在 AT&T 汇编格式中,绝对转移和调用指令(jump/call)的操作数前要加上'*'作为前缀,而在 Intel 格式中则不需要。
6.远程转移指令和远程子调用指令的操作码,在 AT&T 汇编格式中为"ljump" 和 "lcall",而在 Intel 汇编格式中则为 "jmp far" 和 "call far",即:7.与之相应的远程返回指令则为:8.在 AT&T 汇编格式中,内存操作数的寻址方式是section:disp(base, index, scale)而在 Intel 汇编格式中,内存操作数的寻址方式为:section:[base + index*scale + disp]由于 Linux 工作在保护模式下,用的是 32 位线性地址,所以在计算地址时不用考虑段基址和偏移量,而是采用如下的地址计算方法:disp + base + index * scale下面是一些内存操作数的例子:三、Hello World!真不知道打破这个传统会带来什么样的后果,但既然所有程序设计语言的第一个例子都是在屏幕上打印一个字符串 "Hello World!",那我们也以这种方式来开始介绍 Linux 下的汇编语言程序设计。
GNU汇编器as的用户手册。
Here is a brief summary of how to invoke as. For details, see sectionCommand-Line Options.以下是调用as的命令概要,详细内容请见命令行选项一节。
as [ -a[cdhlns][=file] ] [ -D ] [ --defsym sym=val ][ -f ] [ --gstabs ] [ --help ] [ -I dir ] [ -J ] [ -K ] [ -L ][ --keep-locals ] [ -o objfile ] [ -R ] [ --statistics ] [ -v ][ -version ] [ --version ] [ -W ] [ -w ] [ -x ] [ -Z ][ -mbig-endian | -mlittle-endian ][ -m[arm]1 | -m[arm]2 | -m[arm]250 | -m[arm]3 | -m[arm]6 | -m[arm]7[t][[d]m[i]] ] [ -m[arm]v2 | -m[arm]v2a | -m[arm]v3 | -m[arm]v3m | -m[arm]v4 | -m[arm]v4t ] [ -mthumb | -mall ][ -mfpa10 | -mfpa11 | -mfpe-old | -mno-fpu ][ -EB | -EL ][ -mapcs-32 | -mapcs-26 ][ -O ][ -Av6 | -Av7 | -Av8 | -Asparclet | -Asparclite-Av8plus | -Av8plusa | -Av9 | -Av9a ][ -xarch=v8plus | -xarch=v8plusa ] [ -bump ] [ -32 | -64 ][ -ACA | -ACA_A | -ACB | -ACC | -AKA | -AKB | -AKC | -AMC ][ -b ] [ -no-relax ][ -l ] [ -m68000 | -m68010 | -m68020 | ... ][ -nocpp ] [ -EL ] [ -EB ] [ -G num ] [ -mcpu=CPU ][ -mips1 ] [ -mips2 ] [ -mips3 ] [ -m4650 ] [ -no-m4650 ][ --trap ] [ --break ][ --emulation=name ][ -- | files ... ]-a[cdhlmns]Turn on listings, in any of a variety of ways:打开清单输出选项,可以任意使用以下各种方法:-acomit false conditionals忽略假条件-adomit debugging directives忽略调试指示-ahinclude high-level source包含高层源代码-alinclude assembly包含汇编代码-aminclude macro expansions包含宏扩展-anomit forms processing忽略forms处理-asinclude symbols包含符号表=fileset the name of the listing file设置清单文件名You may combine these options; for example, use `-aln' for assembly listingwithout forms processing. The `=file' option, if used, must be the last one.By itself, `-a' defaults to `-ahls'.你可以联合使用这些选项;例如,要获得未经过forms处理的汇编代码清单可使用'-aln',如果要使用‘=file’选项,它必须在最后一个位置,选项‘-a’缺省含义是'-ahls'。
linuxarm汇编语言pdfGNUARM汇编入门pdf在编写标题所描述的内容需求文章时,需要注意字数限制,整洁美观的排版,语句通顺,流畅表达,且无影响阅读体验的问题。
文章可适当增加字数限制,并可以分小节论述。
以下是针对题目“linuxarm汇编语言pdfGNUARM汇编入门pdf”准备的一篇文章:Linux ARM汇编语言与GNU ARM汇编入门引言:汇编语言是一种底层的编程语言,用于与计算机硬件进行交互。
在Linux操作系统下,汇编语言的学习对于理解系统底层运行机制以及进行嵌入式系统开发具有重要意义。
本文旨在介绍Linux ARM汇编语言和GNU ARM汇编入门,帮助读者快速入门和掌握相关知识。
一、了解Linux ARM汇编语言1.1 汇编语言简介汇编语言是一种低级的编程语言,使用助记符来代替机器码,更接近计算机的工作方式。
它具有高度的灵活性和效率,但也需要更多的底层知识。
1.2 Linux系统下的ARM汇编语言Linux操作系统广泛应用于嵌入式系统和服务器领域,而ARM处理器则是其中最常见的架构之一。
学习Linux ARM汇编语言可以帮助我们深入了解计算机系统如何运行以及如何编写高效的嵌入式程序。
二、GNU ARM汇编入门2.1 GNU工具链简介GNU工具链是一套针对ARM架构的开源工具,其中包括编译器、汇编器和链接器等。
使用GNU工具链可以方便地进行ARM汇编开发,并实现与其他高级语言的混合编程。
2.2 GNU ARM汇编语言基础学习GNU ARM汇编语言需要了解基本的寄存器、指令集以及内存访问等。
通过准确理解这些概念,我们可以编写出高效、可靠的汇编代码。
三、实践与案例3.1 汇编语言的应用场景汇编语言在系统底层开发、驱动程序编写、嵌入式系统开发等方面有着广泛应用。
通过实践案例,我们可以更好地理解汇编语言的实际应用和开发流程。
3.2 GNU ARM汇编语言案例分析通过对一些实际的GNU ARM汇编语言案例进行分析和学习,我们可以更好地掌握如何使用GNU工具链进行开发,编写高效的汇编代码。
linuxgcc编译常⽤命令之gun⼯具链的使⽤[cpp] view plain copy print?1. /lesson/id-20331.html2. linux gcc编译常⽤命令之gun⼯具链的使⽤3.4. Binutils源码⼯具包中的常⽤命令:5. gcc g++ ld ldd nm strings readelf addr2line strip6. objcopy as ar gdb7.8. 1、gcc/g++编译器9. ⽰例:10. gcc -c test.c11. gcc -o test test.c12. gcc -E -o test.i test.c13. gcc -g -o test test.c14.15. 2、addr2line 把程序地址转换为⽂件名和⾏号,需要编译时加-g16. ⽰例:17. addr2line a.out -a 804854c18.19. 3、ar 打包提取归档⽂件20. ar rv libtest.a test.o21.22. 4、as gcc⽤来输出汇编⽂件,产⽣⽬标⽂件由连接器ld链接23. ⽰例:24. gcc -S tty.c -o tty.s25. as -o tty.o tty.s26.27. 5、nm 查看导出符号,列出⽬标⽂件的符号28. ⽰例:29. nm -o libtest.so30.31. 6、objcopy ⽂件格式转换32.33. 7、objdump 反编译34. ⽰例:35. objdump -T libtest.so36. objdump -d a.out37.38. 7、ranlib产⽣归档⽂件索引,并将其保存到这个归档⽂件39.40. 8、readelf 显⽰elf格式可执⾏⽂件信息41. ⽰例:42. readelf -h a.out43.44. 9、size 列出⽬标⽂件每⼀段的⼤⼩以及总体⼤⼩45. ⽰例:46. size a.out47.48.49. 10、strings 打印⽬标⽂件中的可打印字符50. ⽰例:51. strings /lib64/libc.so.6 | grep GLIBC_52.53. 11、strip 丢弃⽬标⽂件中的全部或特定符号,减少体积54. ⽰例:55. strip a.out56.57. 12、ldd ⽤于判断某个可执⾏的elf档案引⽤什么动态库58. ⽰例:59. ldd -v libtest.so60.61. 13、查看so导出函数62. nm -D 7z.so63. objdump -tT 7z.so。
在阅读Linux源代码时,你可能碰到一些汇编语言片段,有些汇编语言出现在以.S为扩展名的汇编文件中,在这种文件中,整个程序全部由汇编语言组成,有些汇编命令出自以.c 为扩展名的C文件中,在这种文件中,既有C语言,也有汇编语言,我们把出自现在C代码中的汇编语言叫做“嵌入式”汇编,不管这些汇编代码出现在哪里,它一定程度上都成为了阅读源代码的拦路虎。
尽管C语言已经成为编写操作系统的主要语言,但是,在操作系统与硬件打交道的过程中,在需要频繁调用的函数中以及某些特殊的场合中,C语言显得力不从心,这时繁琐但又高效的汇编语言必须粉墨登场。
因此,在了解一些硬件的基础上,必须对相关的汇编语言知识也有所了解。
读者可能有过在DOS操作系统下编写汇编程序的经历,也具备一定的汇编知识,但是在Linux的源代码中,你可能看到了与Intel的汇编语言格式不一样的形式,这就是AT&T 的386汇编语言。
一,AT&T与Intel汇编语言的比较我们知道,Linux是Unix家族的一员,尽管Linux的历史不长,但与其相关的很多事情都发源于Unix,就Linux所使用的386汇编语言而言,它也是起源于Unix,Unix最初死为PDP-2开发的开发的,曾先后被移植到V AX及68000系列的处理器上,这些处理器上的汇编语言都采用的事A T&T指令格式,当Unix被移植到I386时,自然也就采用AT&T的汇编语言格式,而不是Intel的格式,静这两种汇编语言在语法上有一定的差异,但所基于的硬件知识是相同的。
因此,如果你非常熟悉Intel的语法格式,那么你也可以很容易地把它“移植”到AT&T来,下面我们通过对照Intel与AT&T的语法格式,以便于你把过去的知识能很快的移植过来.1.前缀在Intel的语法中,寄存器和立即数都没有前缀,但是在AT&T中,寄存器前缀以“%”,而立即数前以“$”。
GNU ARM汇编入门第一部分Linux下ARM汇编语法尽管在Linux下使用C或C++编写程序很方便,但汇编源程序用于系统最基本的初始化,如初始化堆栈指针、设置页表、操作ARM的协处理器等。
初始化完成后就可以跳转到C代码执行。
需要注意的是,GNU的汇编器遵循AT&T的汇编语法,可以从GNU的站点()上下载有关规范。
一.Linux汇编行结构任何汇编行都是如下结构:[:][}@comment[:][}@注释Linux ARM汇编中,任何以冒号结尾的标识符都被认为是一个标号,而不一定非要在一行的开始。
【例1】定义一个"add"的函数,返回两个参数的和。
.section.text,“x”.global add@give the symbol add external linkageadd:ADD r0,r0,r1@add input argumentsMOV pc,lr@return from subroutine@end of program二.Linux汇编程序中的标号标号只能由a~z,A~Z,0~9,“.”,_等字符组成。
当标号为0~9的数字时为局部标号,局部标号可以重复出现,使用方法如下:标号f:在引用的地方向前的标号标号b:在引用的地方向后的标号【例2】使用局部符号的例子,一段循环程序1:subs r0,r0,#1@每次循环使r0=r0-1bne1f@跳转到1标号去执行局部标号代表它所在的地址,因此也可以当作变量或者函数来使用。
三.Linux汇编程序中的分段(1).section伪操作用户可以通过.section伪操作来自定义一个段,格式如下:.section section_name[,"flags"[,%type[,flag_specific_arguments]]]每一个段以段名为开始,以下一个段名或者文件结尾为结束。
这些段都有缺省的标志(flags),连接器可以识别这些标志。
标签:GNU ASMGNU-ARM 汇编指令第一部分Linux下ARM汇编语法尽管在Linux下使用C或C++编写程序很方便,但汇编源程序用于系统最基本的初始化,如初始化堆栈指针、设置页表、操作ARM的协处理器等。
初始化完成后就可以跳转到C代码执行。
需要注意的是,GNU的汇编器遵循AT&T的汇编语法,可以从GNU的站点()上下载有关规范。
一. Linux汇编行结构任何汇编行都是如下结构:[:] [} @ comment[:] [} @ 注释Linux ARM 汇编中,任何以冒号结尾的标识符都被认为是一个标号,而不一定非要在一行的开始。
【例1】定义一个"add"的函数,返回两个参数的和。
.section .text, “x”.global add @ give the symbol add external linkageadd:ADD r0, r0, r1 @ add input argumentsMOV pc, lr @ return from subroutine@ end of program二. Linux 汇编程序中的标号标号只能由a~z,A~Z,0~9,“.”,_等字符组成。
当标号为0~9的数字时为局部标号,局部标号可以重复出现,使用方法如下:标号f: 在引用的地方向前的标号标号b: 在引用的地方向后的标号【例2】使用局部符号的例子,一段循环程序1:subs r0,r0,#1 @每次循环使r0=r0-1bne 1f @跳转到1标号去执行局部标号代表它所在的地址,因此也可以当作变量或者函数来使用。
三. Linux汇编程序中的分段(1).section伪操作用户可以通过.section伪操作来自定义一个段,格式如下:.section section_name [, "flags"[, %type[,flag_specific_arguments]]]每一个段以段名为开始, 以下一个段名或者文件结尾为结束。
Linux下的ATT语法(即GNUas汇编语法)⼊门(转载)注:本⽂系转载,⽤于学习。
⼯作这么长时间,⼀直在C语⾔这⼀层⾯上钻研和打拼,⽇积⽉累,很多关于C的疑惑在书本和资料中都难以找到答案。
程序员是追求完美的⼀个种群,其头脑中哪怕是存在⼀点点的思维⿊洞都会让其坐卧不宁。
不久前在itput论坛上偶得《Computer Systems A Programmer's Perspective》(以下称CS.APP)这本经典好书,遂连夜拜读以求解惑。
虽说书中没有能正⾯的回答我的⼀些疑惑,但是它却为我指明了⼀条通向 “⽆惑”之路 -- 这就是打开汇编之门。
汇编语⾔是⼀门⾮常接近机器语⾔的语⾔,其语句与机器指令之间的对应关系更加简单和清晰。
打开汇编之门不仅仅能解除⾼级语⾔给你带来的疑惑,它更能让你更加的理解现代计算机的运⾏体系,还有⼀点更加重要的是它给你带来的是⼀种⾃信的感觉,减少了你在⾼处摇摇欲坠的恐惧,响应了侯捷⽼师的“勿在浮沙筑⾼台”的号召。
现在学习汇编的⽬的已与以前⼤⼤不同了。
正如CS.APP中所说那样“程序员学习汇编的需求随着时间的推移也发⽣了变化,开始时是要求程序员能直接⽤汇编编写程序,现在则是要求能够阅读和理解优化编译器产⽣的代码”。
能阅读和理解,这也恰恰是我的需求和⽬标。
在⼤学时接触过汇编,主要是Microsoft MASM宏汇编,不过那时的认识⾼度不够加上态度不端正,错失了⼀个很好的学习机会。
现在绝⼤部分时间是使⽤GCC在Unix系列平台上⼯作,选择汇编语⾔当然是GNU汇编了,恰好CS.APP中使⽤的也是GNU的汇编语法。
由于学习汇编的主要⽬的还是“解惑”,所以形式上多是以C代码和汇编代码的⽐较。
1、汇编让你看到更多随着你使⽤的语⾔的层次的提⾼,你眼中的计算机将会越来越模糊,你的关注点也越来越远离语⾔本⾝⽽靠近另⼀端“问题域”,⽐如通过JAVA,你更多看到的是其虚拟机,⽽看不到真实的计算机;通过C,你看到的也仅仅是内存⼀层;到了汇编语⾔,你就可以深⼊到寄存器⼀层⾃由发挥了。
第一部分 Linux下ARM汇编语法尽管在Linux下使用C或C++编写程序很方便,但汇编源程序用于系统最基本的初始化,如初始化堆栈指针、设置页表、操作 ARM的协处理器等。
初始化完成后就可以跳转到C代码执行。
需要注意的是,GNU的汇编器遵循AT&T的汇编语法,可以从GNU的站点()上下载有关规范。
一. Linux汇编行结构任何汇编行都是如下结构:[:] [} @ comment[:] [} @ 注释Linux ARM 汇编中,任何以冒号结尾的标识符都被认为是一个标号,而不一定非要在一行的开始。
【例1】定义一个"add"的函数,返回两个参数的和。
.section .text, “x”.global add @ give the symbol add external linkageadd:ADD r0, r0, r1 @ add input argumentsMOV pc, lr @ return from subroutine@ end of program二. Linux 汇编程序中的标号标号只能由a~z,A~Z,0~9,“.”,_等字符组成。
当标号为0~9的数字时为局部标号,局部标号可以重复出现,使用方法如下:? 标号f: 在引用的地方向前的标号? 标号b: 在引用的地方向后的标号【例2】使用局部符号的例子,一段循环程序1:subs r0,r0,#1 @每次循环使r0=r0-1bne 1f @跳转到1标号去执行局部标号代表它所在的地址,因此也可以当作变量或者函数来使用。
三. Linux汇编程序中的分段(1).section伪操作用户可以通过.section伪操作来自定义一个段,格式如下:.section section_name [, "flags"[, %type[,flag_specific_arguments]]]每一个段以段名为开始, 以下一个段名或者文件结尾为结束。
7 汇编器命令所有的汇编器命令名都由句号('.')开头。
命令名的其余是字母,通常使用小写。
本章讨论可用命令,不理会gun汇编器针对目标机器配置。
某些机器的配置提供附加的命令。
7.1 .abort本命令立即终止汇编过程。
这是为了兼容其它的汇编器。
早期的想法是汇编语言的源码会被输送进汇编器。
如果发送源码的程序要退出,它可以使用本命令通知as退出。
将来可能不再支持使用.abort7.2 .ABORT当生成COFF输出时,汇编器把这条命令作为.abort接受。
当产成b.out输出时,汇编器允许使用这条命令,但忽略它。
7.3 .align abs-expr, abs-expr, abs-expr增加位置计数器(在当前的子段)使它指向规定的存储边界。
第一个表达式参数(结果必须是纯粹的数字)是必需参数:边界基准,见后面的描述。
第二个表达式参数(结果必须是纯粹的数字)给出填充字节的值,用这个值填充位置计数器越过的地方。
这个参数(和逗点)可以省略,如果省略它,填充字节的值通常是0。
但在某些系统上,如果本段标识为包含代码,而填充值被省略,则使用no-op指令填充这个空间。
第3个参数表达式的结果也必须是纯粹的数字,这个参数是可选的。
如果存在第3个参数,它代表本对齐命令允许越过字节数的最大值。
如果完成这个对齐需要跳过的字节比指定的最大值还多,则根本无法完成对齐。
您可以在边界基准后简单地使用两个逗号,以省略填充值参数(第二参数);如果您想在适当的时候,对齐操作自动使用no-op指令填充,这个方法将非常奏效。
边界基准的定义因系统而有差异。
a29k,hppa,m68k,m88k,w65,sparc,Hitachi SH, 和使用ELF格式的i386,第一个表达式是边界基准,单位是字节。
例如‗.align 8‘向后移动位置计数器至8的倍数。
如果地址已经是8的倍数,则无需移动。
有些其它系统,包括使用a.out格式的i386,ARM和strongarm,这代表位置计数器移动后,计数器中连续为0的低序位数量。