AT&T x86_32 汇编_003_数据段

以上两节讲解了两个简单的示例程序, 从这一节开始, 就要接触到枯燥的细节了.

1. 在数据段中定义"全局变量"

在前面两讲中, 我们分别以.ascii.asciz, 在数据段定义过字符串数据. 如下这样:

.section .data
output1:
    .ascii "The processor Vendor ID is ‘xxxxxxxxxxxx‘\n"

output2:
    .asciz "The processor Vendor ID is ‘%s‘\n"

我们可以把output1output2理解为全局变量.

在数据段中定义数据元素需要用到两个语句:

  1. 标签语句. 用以给"变量"起名字, 即是output1:output2:
  2. 命令语句. 用以给"变量"赋值.

数据的本质, 就是内存中的一段连续单元, 那么标签的本质是什么呢?

  1. 标签对cpu是没有意义的, 标签像极了高级语言中的变量名(单指值类型语言), 它本质上是内存区域的一个别名.
  2. 在汇编语言中, 标签是写给程序员看的. 而汇编代码经过编译链接后, 标签就会转换为内存中的地址.

除了标签之外, 还必须定义为数据元素保留多少字节. 保存内存的数量取决于数据的类型, 以及如果是多个重复数据的话, 还有数据的数量.

下面是数据声明命令:

命令 意义
.ascii 文本字符串
.asciz 以\0结尾的文本字符串
.byte 一个字节
.double 一个双精度浮点数
.float 一个单精度浮点数
.int 32位整数
.long 32位整数
.octa 16(128位)字节整数
.quad 8(64位)字节整数
.short 16位整数
.single 单精度浮点数, 同.float

下面是正确示例:

.section .data
pi:
    .float 3.1415926        # 定义了一个单精度浮点数

sizes:
    .long 100, 150, 200, 250, 300   # 定义了一个数组, 数组中的元素均为32位整数, 数组共有5个元素

按数据段中, 各个标签数据定义的顺序, 各个数据元素将被按顺序存放在内存中. 带有多个值的元素(数组)也按顺序存放.

数据段中除了能够定义"变量"之外, 还能定义"静态符号". 所谓的"静态符号", 可以理解为类似于C语言中"宏值"的概念, 或者C++中"constexpr"的概念. 它不指代内存空间, 只是一个值的别名. 如下:

.section .data

.equ factor, 3
.equ LINUX_SYS_CALL, 0x80

.section .text
.globl _start
_start:
    movl $LINUX_SYS_CALL, %eax      # 实际上等价于 movl $0x80, %eax

2. 在bss段中声明缓冲区变量

C编程中很重要的一个基础技法就是, 做数据操作前先声明一个字符数组做缓冲区, 在读写过程中, 以缓冲区为中介, 暂存数据.

缓冲区的特点主要是:

  1. 一般情况下是一段有限长度的连续内存空间.
  2. 使用前不需要进行初始化

由于缓冲区使用前不需要进行初始化, 也无必要, 所以将缓冲区声明为全局变量或局部静态变量是一个很好的主意: 这种变量默认值为0, 且正因为C的机制使这种变量的初始化值为0, 这种变量在编译链接后的可执行文件中, 位于bss段, 不占用文件空间. bss段的size是为0字节!

我们在上一讲, 使用printf输出cpu厂商信息的示例程序中, 就使用了一个声明了bss段中的缓冲区, 声明尺寸为12字节, 用于暂存厂商的12个字符, 代码片段如下:

.section .bss
    .lcomm buffer 12

需要注意的是, bss段不占空间, 仅是指在程序编译链接后生成的二进制可执行文件中, bss段的长度为0. 但这个bss段依然在文件段表中有自己的段描述符. 并且在文件被操作系统装载, 成为进程后, bss段中声明的所有数据, 都会按照声明的长度在进程内存中占用对应的空间.

"未初始化的全局或局部静态变量"的声明, 和数据段中的"全局变量"声明, 写法不太一样. 变量名不是通过"标签语句"给出的, 而是在lcommcomm命令中给出的. 命令后紧跟变量名, 再跟数据宽度

在bss段中声明变量有两个命令可以使用, 如下:

命令 意义
.comm 声明未初始化的数据的通用内存区域
.lcomm 声明未初始化的数据的本地通用内存区域

语法为: .comm symbol, length, 其中length的单位是字节

.lcomm中的l的含义是local, 即为本地的, 即通过.lcomm声明的变量, 无法被外部文件引用.

原文地址:https://www.cnblogs.com/neooelric/p/9693653.html

时间: 2024-10-29 16:16:31

AT&T x86_32 汇编_003_数据段的相关文章

汇编的数据段和栈

1.DS和[address] 例如:我们要读取10000H单元的内容可以用如下程序进行 mov bx,1000H mov ds,bx mov al,[0] 上面的三条指令是将10000H(1000:0)中的数据读到al中. [...]表示一个内存单元,[...]中的0表示内存单元的偏移地址.我们知道只有偏移地址是不能定位一个内存单元的,那么内存单元的段地址是多少呢?指令执行时,8086CPU自动获取ds中的数据位内存单元的段地址. 再来看一下,我们如何用mov指令从10000H中读取数据.100

比较分别在数据段与附加段中的字符串以及汇编中常见的四种中断指令

1.从键盘输入两个相同长度的字符串,分别放到数据段和附加段,利用串比较指令比较数据段和附加段中两个字符串,如果两串一样,输出Y,否则输出N. 这个程序调试了好久,之间遇到两个问题,其一是附加段的使用,需要对DS压栈对ES调整处理,即 1 PUSH DS 2 MOV AX,ES 3 MOV DS,AX 4 ;...... 5 POP DS 其二是,串比较指令CMPSW进行字比较,而CMPSB进行字节比较,需要区分开.(其实我现在还不明白即便是字符组成的串,进行字比较为什么会出错,有高手知道吗?)

LINUX下目标文件的BSS段、数据段、代码段

http://blog.chinaunix.net/uid-27018250-id-3867588.html bss 未初始化的全局数据 data 已经初始化的全局数据 text 代码段,机器指令 rodata 字符串常量 参考:<程序员自我修养> 代码编译后的机器指令经常被放在代码段里,代码段名为".text";已初始化的全局变量和已初始化的局部静态变量经常放在数据段里,数据段名为".data";未初始化的全局变量和未初始化局部静态变量一般放在“.bs

汇编语言——寄存器(内存访问 ds数据段寄存器,ss栈段寄存器)

在内存中字的存储 这段话的主要意思是:一个字=2B=16bit,CPU中是用两个内存单元储存一个字(假如获取0地址存放的字型数据,就是获取它的高位字节0+1位和低位字节0位的数据,数据由高地址位向低地址位读) 问题: (1)0地址单元中存放的字节型数据是多少? #  20H(2)0地址字单元中存放的字型数据是多少? # 4e20H(3)2地址字单元中存放的字节型数据是多少? # 12H(4)2地址单元中存放的字型数据是多少?    #  0012H(5)1地址字单元中存放的字型数据是多少? #

AT&amp;T x86_32 汇编_001_一个示例程序.md

这一节先写一个简单的汇编程序. 输出cpu的出产厂商. 不对语法, 寄存器等内容进行深入讨论, 只是整体上先有个认知印象. 1. 一些基础知识 简单来说, Linux下的可执行程序文件中, 最重要的三个部分是: 数据段, 代码段, bss段. 关于可执行文件, 以及目标文件的内容构成, 其实这是一个十分复杂的话题, 这里不进行深入讨论, 你可以简单的理解为: 可执行文件由段(section)组成. 每个可执行文件中存在多个段. 段是一种划分可执行二进制程序内容的手段 其中最重要的三个段: 数据段

转:程序内存空间(代码段、数据段、堆栈段)

https://blog.csdn.net/ywcpig/article/details/52303745 在冯诺依曼的体系结构中,一个进程必须有:代码段,堆栈段,数据段. 进程的虚拟地址空间图示如下: BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域.数据

IP包、TCP报文、UDP数据段格式的汇总

一.IP包格式 IP数据包是一种可变长分组,它由首部和数据负载两部分组成.首部长度一般为20-60字节(Byte),其中后40字节是可选的,长度不固定,前20字节格式为固定.数据负载部分的长度一般可变,整个IP数据包的最大长度为65535B. 1.版本号(Version) 长度为4位(bit),IP v4的值为0100,IP v6的值为0110. 2.首部长度 指的是IP包头长度,用4位(bit)表示,十进制值就是[0,15],一个IP包前20个字节是必有的,后40个字节根据情况可能有可能没有.

BSS段、数据段、代码段、堆与栈

BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域. BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域. 数据段属于静态内存分配. 代码段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区 域.这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读

内存分配(堆、栈、BSS、代码段、数据段)

这两天看了马士兵老师的视频.视频中提到了一个万能钥匙.就是了解程序运行中对内存的操作.主要讲了堆.栈.Data.说真的有点晕.看了两遍.也就略懂一二.在这做个小小知道总结 简介 我们程序运行的时候都是放在内存里的.根据静态.成员函数.代码段.对象.等等.放在不同的内存分块里.大概分为5块 1  栈 2  堆 3 BSS段-全局区-(静态区) 4 代码段 5 数据段 栈 存放局部变量.临时变量.声明.返回值.指向堆对象的地址(指针).总之存放一些小的东西.当不需要时候.栈会自动清除.比如一个加法方