(6).asciz命令用于在字符串的末尾添加空字符’\0’。
(7)用汇编调用c库时,注意参数放入堆栈的顺序和c函数获取他们的顺序是相反的。还要注意尽管使用ld的-l参数指定库名称,但是还要使用-dynamic-linker来指定另外一个库,这个库是运行时加载动态库的程序,linux下为ld-linux.so.2。
(8)注意avr单片机是不能使用动态链接库的,不排除你在avr单片机上面自己做一个操作系统,然后再自己做一个加载动态库的程序。但是avr单片机使用静态库是很常见的,其实静态库就是一份copy,需要哪个模块就复制哪个模块的目标代码到可执行文件中。需要注意的是,在linux操作系统中glibc库就是c的标准库,这个库时一个动态库,一般随linux安装,gcc只是一个编译器,也就是说c的标准库一般都是系统提供的。这个c的标准动态库也可能存在调用了linux系统的库。
(9)数据段定义:
.data声明的数据段中的任何数据元素都保留在内存中,并且可以被汇编语言程序中的指令读取和写入。
.rodata声明的数据段中的任何数据元素只能按照只读模式访问。
在数据段中定义数据元素要用到两个语句:一个标签和一个命令。
标签对处理器是没有意义的,它只是汇编器试图访问内存位置时,用作引用指针的一个位置。
汇编器命令指示汇编器为通过标签引用的数据元素保留特定数量的内存。
声明命令之后,必须定义一个(或者多个)默认值。这样把保留的内存位置中的数据设置为特定值。
.byte:字节值
.ascii:文本字符串
.asciz:以空字符结尾的文本字符串
.double:双精度浮点数
.float :单精度浮点数
.int:32位整数
.long:32位整数(和 .int相同)
.octa:16字节整数
.quad:8字节整数
.short:16位整数
.single:单精度浮点数(和.float相同)
在定义一个静态符号时使用.equ,例如: .equ factor, 3
Movl $factor, %eax 这是引用静态符号的方法,使用’$’。静态符号在定义好之后就不能再改变了。静态符号其实就是相当于define factor 3。在汇编的时候movl $factor, %eax就会被替换成movl $3, %eax 这才是本质。
(10).bss段中定义数据元素和在数据段.data中定义有些不同。无须声明特定的数据类型,只要声明为所需的保留的原始内存部分即可。
使用两个命令声明缓冲区:
.comm: 声明未初始化的数据的通用内存区域
.lcomm:声明未初始化的数据的本地通用内存区域
虽然这两种区域工作情况类似,但是本地通用内存区域是为不会从本地汇编代码之外进行访问的数据保留的。
注意:在.bss段声明数据,数据不包括在最终的可执行程序中,内存区域被保留在运行时使用。
.fill:命令用于创建n个字节,并用0填充,并且添加到最终的可执行代码中。例如:.fill 5
(11)在数据传送中,需要注意的是:
在使用变址的内存位置表示数组的时候:
Base_address( offset_address, index, size)
获取的数据值位于:base_address + offset_address + index * size
注意:offset_address和index的值必须是寄存器。
例如:movl value(%eax, %edi, 4), %ecx
(12)在间接寻址时使用‘( )’。
例如:movl %ebx, (%edi) 把EBX寄存器中的值传送给EDI寄存器中的内存地址中。
Movl %ebx, 4(%edi) 把EBX中的值传送给EDI中内存地址的之后4字节的内存地址中。
Movl %ebx, -4(%edi) 于上相反。