|
板凳

楼主 |
发表于 2009-12-4 19:55:50
|
只看该作者
bss 段
在 bss 段中定义数据元素和在数据段中定义有些不同。在这里无须声明特定的数据类型,只要声明为所需目的的保留的原始内存部分即可。
GNU汇编器使用两个命令声明缓冲区,如下表所示:
命令
| 描述
| .comm
| 声明未初始化的数据的通用内存区域
| .lcomm
| 声明未初始化的数据的本地通用内存区域
|
虽然这两种区域的工作情况类似,但是本地通用内存区域是为不会从本地汇编代码之外进行访问的数据保留的。这两个命令的格式是:其中,symbol 是赋给内存区域的标签,length 是内存区域中包含的字节数量,如下面所示:.section .bss
.lcomm buffer, 10000 上面,把 10000 字节的内存区域赋值给 buffer 标签。在声明本地通用内存区域的程序之外的函数是不能访问它们的( 不能在 .global 命令中使用它们 ),所以这些区域通常也不为 ld 连接器所见。
在 bss 段中声明数据的一个好处是数据不包括到可执行程序中,而在数据段中定义的数据则会被包括到可执行程序里---因此必须对这些数据进行赋初值初始化。正是由于不对 bss 段中的数据进行初始化,所以所声明的内存区域也被保留到运行时使用。
下面分别比较一下 3 个程序的大小:
程序1代码:# size.s - A sample program to view the executable size
.section .text
.globl _start
_start:
movl $1, %eax
movl $0, %ebx
int $0x80 编译成可执行文件后大小为:$ ls -l size
-rwxr-xr-x 1 beyes beyes 460 2009-12-04 19:47 size
程序2代码:# size2.s - A sample program to view the executable size
.section .bss
.lcomm buffer, 10000
.section .text
.globl _start
_start:
movl $1, %eax
movl $0, %ebx
int $0x80 编译成可执行文件后大小为:$ ls -l size2
-rwxr-xr-x 1 beyes beyes 575 2009-12-04 19:49 size2
程序3代码:# size3.s - A sample program to view the executable size
.section .data
buffer:
.fill 10000
.section .text
.globl _start
_start:
movl $1, %eax
movl $0, %ebx
int $0x80 编译成可执行文件后大小为:$ ls -l size3
-rwxr-xr-x 1 beyes beyes 10575 2009-12-04 19:50 size3 在 程序3 中使用 .fill 命令使汇编器自动创建 10 000 个数据元素,默认为每个字段创建一个字节,并且使用零来填充。
比较程序3 和 程序2 ,可见程序3的文件长度大大增加了,因为缓冲区的 10 000 个字节被添加到了可执行文件中。
关于 .fill 命令
.fill 命令的完整格式是:.fill repeat, size, value repeat 是要重复填充的次数
size 是每次填充时要填充多少个字节(不大于8,大于8也会是8)
value 用什么值来填充
修改一下上面的程序3代码:
.section .data
buffer:
.fill 10000, 4, 8
output:
.asciz "ouput buffer %d\\n"
.section .text
.globl main
main:
pushl buffer
pushl $output
call printf
addl $8, %esp
pushl buffer+4
pushl $output
call printf
addl $8, %esp
movl $1, %eax
movl $0, %ebx
int $0x80 输出:./size32
ouput buffer 8
ouput buffer 8 |
|