操作系统学习_Linux0.12_as汇编

来源:互联网 发布:头影测量软件 编辑:程序博客网 时间:2024/03/29 23:28

as: GNU组织推出的一款汇编语言编译器,它支持多种不同类型的处理器。

语法
as(选项)(参数)
选项
-ac:忽略失败条件;
-ad:忽略调试指令;
-ah:包括高级源;
-al:包括装配;
-an:忽略形式处理;
-as:包括符号;
=file:设置列出文件的名字;
–alternate:以交互宏模式开始;
-f:跳过空白和注释预处理;
-J:对于有符号溢出不显示警告信息;
-o:指定输出的目标文件名;
-a:开启程序列表;
-f:快速操作;
-R:组合数据区和代码区;
-W:取消警告信息;
–statistics:打印汇编所用的最大空间和总时间。


as使用的ATT语法与Intel汇编使用的语法有很大区别,主要的区别如下:
一、ATT语法中立即数前要加“$”,寄存器前要加“%”,绝对跳转和调用前要加“*”
二、ATT语法的源操作数与目的操作数刚好和Intel语法相反,例:

ATT:addl $4,%eaxIntel:add eax,4

三、ATT语法中内存操作数的长度由操作码最后一个字符决定
b:8位byte字节
w:16位word字
l:32位long长字
Intel语法则是使用前缀

byte ptrword ptrdword ptr

例:

ATT:movb $foo,%alIntel:mov al, byte ptr foo

四、ATT语法中立即形式的远跳转或远调用为

ljmp/lcall $section,$offest

而Intel的是

jmp/call far section:offest

远返回指令同理。

五、ATT汇编器没有多段代码支持,UNIX类操作系统要求所有代码在一个段中。


as汇编器支持的转义字符

\b  退格符0x08\f  换页符0x0C\n  换行符0x0A\r  回车符0x0D\NNN    3个八进制数表示的字符代码\xNN... 16进制数表示的字符代码\\  表示一个反斜杠字符\"  表示字符串中的双引号""

ATT与Intel转换指令对应关系

ATT             Intel                 说明    cbtw            cbw                 把%al中的字节值符号扩展到%ax中cwtl            cwde                把%ax符号扩展到%eax中cwtd            cwd                 把%ax符号扩展到%dx:%ax中cltd            cdq                 把%eax符号扩展到%edx:%eax

指令操作码前缀

操作码前缀               说明cs,ds,ss,es,fs,gs       区覆盖操作码前缀lock                    总线锁存前缀wait                    协处理器指令前缀rep,repe,repne          串指令操作前缀data16,addr16           操作数/地址宽度前缀

区覆盖:通过指定使用 区:内存操作数 内存引用形式会自动添加此前缀
总线锁:在指令执行期间禁止中断
协处理器:等待协处理器完成当前指令的执行
串指令:使串指令重复执行%eax中指定的次数
操作数/地址宽度:将32位操作数/地址改变成16位操作数/地址


内存引用

ATT:section:disp(base, index, scale)Intel:section:[base+index*scale+disp]

其中base和index是可选的32位基寄存器和索引寄存器,disp是可选的偏移值,scale是比例因子,取值范围为1,2,4,8。scale乘以index用来计算操作数地址,scale默认取1。section为内存操作数指定可选的段寄存器,会覆盖操作数使用的当前默认段寄存器。


区&重定位

在目标文件中的顺序:

.text  .data  .bss

要注意的是,绝对地址区(absolute区)的地址始终不变,多个目标文件的absolute区相同时,会覆盖到一起。


as汇编命令
汇编命令是指示汇编器操作方式的伪指令。汇编命令用于要求汇编器为变量分配空间、确定程序开始地址、指定当前汇编的区、修改位置计数器值等。所有汇编命令的名称都以”.”开始,其余是字符,并且大小写无关。但是通常都使用小写字符。下面我们给出一些常用汇编命令的说明。

1..align abs-expr1, abs-expr2, abs-expr3
.align是存储对齐汇编命令,用于在当前子区中把位置计数器值设置(增加)到下一个指定存储边界处。第1个绝对值表达式abs-expr1(Absolute Expression)指定要求的边界对齐值。对于使用a.out格式目标文件的80x86系统,该表达式值是位置计数器值增加后其二进制值最右面0值位的个数,即是2的幂值。例如,”.align 3”表示把位置计数器值增加到8的倍数上。如果位置计数器值本身就是8的倍数,那么就无需改变。但是对于使用ELF格式的80x86系统,该表达式值直接就是要求对齐的字节数。例如”.align 8”就是把位置计数器值增加到8的倍数上。
第2个表达式给出用于对齐而填充的字节值。该表达式与其前面的逗号可以省略。若省略,则填充字节值是0。第3个可选表达式abs-expr3用于指示对齐操作允许填充跳过的最大字节数。如果对齐操作要求跳过的字节数大于这个最大值,那么该对齐操作就被取消。若想省略第2个参数,可以在第1和第3个参数之间使用两个逗号。

2..ascii “string”…
从位置计数器所指当前位置为字符串分配空间并存储字符串,可使用逗号分开写出多个字符串。例如,”.ascii “Hello world!”, “My assembler”“。该汇编命令会让as把这些字符串汇编在连续的地址位置处,每个字符串后面不会自动添加0(NULL)字节。

3..asciz “string”…
该汇编命令与”.ascii”类似,但是每个字符串后面会自动添加NULL字符。

4..byte expressions
该汇编命令定义0个或多个用逗号分开的字节值。每个表达式的值是1字节。

5..comm symbol, length
在bss区中声明一个命名的公共区域。在ld链接过程中,某个目标文件中的一个公共符号会与其他目标文件中同名的公共符号合并。如果ld没有找到一个符号的定义,而只是一个或多个公共符号,那么ld就会分配指定长度length字节的未初始化内存。length必须是一个绝对值表达式,如果ld找到多个长度不同但同名的公共符号,ld就会分配长度最大的空间。

6..data subsection
该汇编命令通知as把随后的语句汇编到编号为subsection的data子区中。如果省略编号,则默认使用编号0。编号必须是绝对值表达式。

7..desc symbol, abs-expr
用绝对表达式的值设置符号symbol的描述符字段n_desc的16位值。仅用于a.out格式的目标文件。参见有关include/a.out.h文件的说明。

8..fill repeat, size, value
该汇编命令会产生数个(repeat个)大小为size字节的重复拷贝。大小值size可以为0或某个值,但是若size大于8,则限定为8。每个重复字节内容取自一个8字节数。高4字节为0,低4字节是数值value。这3个参数值都是绝对值,size和value是可选的。如果第2个逗号和value省略,value默认为0值;如果后两个参数都省略,则size默认为1。

9..global symbol (或者.globl symbol)
该汇编命令会使得链接器ld能看见符号symbol。如果在我们的目标文件中定义了符号symbol,那么它的值将能被链接过程中的其他目标文件使用。若目标文件中没有定义该符号,那么它的属性将从链接过程中其他目标文件的同名符号中获得。这是通过设置符号symbol类型字段中的外部位N_EXT来做到的。参见include/a.out.h文件中的说明。

10..int expressions
该汇编命令在某个区中设置0个或多个整数值(80386系统为4B,同.long)。每个用逗号分开的表达式的值就是运行时刻的值,如”.int 1234, 567, 0x89AB”。

11..lcomm symbol, length
为符号symbol指定的局部公共区域保留长度为length字节的空间。所在的区和符号symbol的值是新的局部公共块的值。分配的地址在bss区中,因此在运行时刻这些字节值被清零。由于符号symbol没有被声明为全局的,因此链接器ld看不见。

12..long expressions
含义与.int相同。

13..octa bignums
这个汇编命令指定0个或多个用逗号分开的16B大数(.byte, .word, .long, .quad, .octa 分别对应1、2、4、8和16字节数)。

14.org new_lc, fill
这个汇编命令会把当前区的位置计数器设置为值new_lc。new_lc是一个绝对值(表达式),或者是具有相同区作为子区的表达式,即不能使用.org跨越各区。如果new_lc的区不对,那么.org就不会起作用。请注意,位置计数器是基于区的,即以每个区作为计数起点。
当位置计数器值增长时,所跳跃过的字节将被填入值fill。该值必须是绝对值。如果省略了逗号和fill,则fill默认为0值。

15..quad bignums
这个汇编命令指定0个或多个用逗号分开的8B大数bignum。如果大数放不进8B中,则取低8B。

16..short expressions (同.word expressions)
这个汇编命令指定某个区中0个或多个用逗号分开的2字节数。对于每个表达式,在运行时刻都会产生一个16位的值。

17..space size, fill
该汇编命令产生size个字节,每个字节填值fill。这个参数为绝对值。如果省略了逗号和fill,那么fill的默认值就是0。

18..string “string”
定义一个或多个用逗号分开的字符串。在字符串中可以使用转义字符。每个字符串都自动附加一个NULL字符结尾。例如,”.string “\n\nStarting”, “other strings”“。

19..text subsection
通知as把随后的语句汇编进编号为subsection的子区中。如果省略了编号subsection,则使用默认编号值0。

20..word expressions
对于32位机器,该汇编命令含义与.short相同。

原创粉丝点击