Linux汇编之数据定义

汇编 2015年03月02日 ,

汇编定义数据 汇编语言(ASM)程序重要的任务之一就是处理数据对象,在汇编语言程序中必须管理各种类型的数据对象。枫竹梦在本文将介绍Linux汇编语言中如何定义数据元素。 GNU汇编器提供了在汇编语言程序中定义和处理数据元素的多种方式,可以根据应用程序的需要选择最佳的数据元素。数据段和bss段提供了定义数据元素的方法。

数据段

程序的数据段定义的数据元素存储在程序特定的内存位置。使用.data命令声明数据段,可以被程序中的指令码引用,随意的读取和修改。.rodata命令声明的数据段中能按只读(read-only)模式访问。 在数据段定义数据元素需要用到两个语句:

  • 标签
  • 命令

标签是引用数据元素所使用的标记,它与C语言中的变量名称相似。标签对处理器是没有意义的,它只是汇编器试图访问内存位置时用作引用指针的一个位置。 命令用于指明为数据元素保留多少字节的空间。保留的内存数量取决无定义的数据类型,及这种类型数据的个数。声明命令之后,必须指定一个(或者多个)默认值。这样把保留的内存位置中的数据设置为特定值。 下表是不同数据类型对应的命令:

命令 描述
.ascii 文本字符串
.asciz 以空字符结尾的文本字符串
.byte 字节值
.double 双精度浮点数
.float 单精度浮点数
.int 32位整数
.long 32位整数(与.int相同)
.octa 16字节整数
.quad 8字节整数
.short 16整数
.single 单精度浮点数(与.float相同)

上一文中定义的如下内容:

output:
.ascii "The processor Vendor ID is 'xxxxxxxxxxxx'\n"

上述代码定义一段文本字符串,其长度由提供的默认值决定,这里为42字节长度。同时output标签引用地址为该字符串的第一个字节的地址。 还可以定义其他类型的数据元素,如浮点数:

pi:
.float 3.14159

还可以在一条命令中定义多个值,每个值用逗号(,)分隔,每个值按顺序存储在内存中,类似于C语言中的数组,如:

sizes:
.long 100, 150

知道每个整数的长度为4个字节,可以通过sizes+4来访问150这个值。 在数据段中,可以按需要定义多个值,如:

.section .data
msg:
.ascii "This is furzoom.com"
factors:
.double 1.1, 1.2, 1.3
height:
.int 100
length:
.int 10, 20, 30

按照数据段中定义数据元素的顺序,每个元素被顺序的放入内存当中。

定义静态符号

虽然数据段主要用于定义变量数据,但是也可以声明静态数据符号。.equ命令用于把常量值设置为可以在文本段中使用符号,如:

.section .data
.equ factor, 1
.equ LINUX_SYS_CALL, 0x80

静态符号不能在程序中改动。为了引用静态数据元素,必须在标签名称前而使用美元符号($),如:

movl $factor, %eax

bss段

bss段中声明的数据元素和在数据段中定义有所不同。bss段中的数据没有特定类型,但在显示说明要保留的内存大小。在bss段中声明的数据元素常称为缓冲区。另外,bss段在程序加载时会被填充为0。在bss段中声明缓冲区的命令如下:

命令 描述
.comm 声明未初始化的数据的通用区域
.lcomm 声明未初始化的数据的本地通用区域

.lcomm声明的本地通用内存区域只能由本文件内指令使用,而由.comm声明的通用内存区域可以通过ld命令被其他文件中指令使用。如:

.comm symbol, length

symbol为标签,表示内存地址;length内存区域保留字节数。如:

.section .bss
.lcomm buffer, 1000

保留1000个字节的内存区域,buffer标签为其起始地址。使用.lcomm声明的缓冲区不能被本文件之外的函数使用,不能在.globl命令中使用它们。 在bss段中声明的数据元素不包含在可执行程序中,而在数据段声明的数据元素,将被包含在可执行程序中,因为它们包含特定的初始值。 对比如下三段程序:

# sizetest1.s - By furzoom @ Mar 2, 2015
.section .text
output:
.fill 1
.section .bss
.lcomm buffer, 1
.globl _start
_start:
movl $1, %eax
movl $0, %ebx
int $0x80

# sizetest2.s - By furzoom @ Mar 2, 2015
.section .text
output:
.fill 1001
.section .bss
.lcomm buffer, 1
.globl _start
_start:
movl $1, %eax
movl $0, %ebx
int $0x80

# sizetest3.s - By furzoom @ Mar 2, 2015
.section .text
output:
.fill 1
.section .bss
.lcomm buffer, 1001
.globl _start
_start:
movl $1, %eax
movl $0, %ebx
int $0x80

.fill命令使汇编器自动地创建1001个数据元素,默认每个字段是一个字节,并用零填充。将三段程序分别汇编并连接,结果大小如下:

$ ls -l sizetest?
-rwxrwxr-x 1 mn mn  590 Feb 27 17:18 sizetest1
-rwxrwxr-x 1 mn mn 1590 Feb 27 17:23 sizetest2
-rwxrwxr-x 1 mn mn  590 Feb 27 17:21 sizetest3
$

从结果看,.data段的变量空间被增加到可执行程序内,而.bss段的变量并没有增加到可执行程序内。
(完)

如无特别说明,本站文章皆为原创,若要转载,务必请注明以下原文信息:
日志标题:《Linux汇编之数据定义》
日志链接:http://furzoom.com/linux-asm-define-data/
博客名称:枫竹梦

发表评论

插入图片

NOTICE1:请申请gravatar头像,没有头像的评论可能不会被回复!

回到顶部