5.汇编语言程序设计基础之传送数据
如何定义数据元素:
1. 数据段:
- 使用.data命令声明数据段,在这个段中声明的任何数据元素都保留在内存中并且可以被汇编语言程序中的指令读取和写入。
- 使用.rodata命令声明数据段,在这个段中定义的任何数据元素只能按照只读模式访问
数据段定义数据元素需要用到两个语句:一个标签和一个命令。标签用作引用数据源叔所使用的标记(理解为变量名称),时汇编器试图访问内存位置时用作引用的指针的一个位置。
命令 | 数据类型 |
---|---|
.ascli | 文本字符串 |
.asciz | 以空字符结尾的文本字符串 |
.byte | 字节值 |
.double | 双精度浮点数 |
.float | 单精度浮点数 |
.int | 32位整数 |
.long | 32位整数(和.int相同) |
.octa | 16字节数整数 |
.quad | 8字节数证书 |
.short | 16位整数 |
.single | 单精度浮点数(和.float相同) |
用数据段定义数据元素示例:
output:
.ascii “The processor Vendor ID is ‘xxxxxxxx’\n”
定义了output字符串
pi:
.float 3.14159
定义了pi变量
一个命令语句可以定义多个值,例如:
sizes:
.long 100,150(+4),200(+8)
2. 定义静态符号:
虽然数据段主要用于定义变量数据,但是也可以在这里声明静态数据符号。.equ命令用于把常量值设置为可以在文本中使用的符号,例如:
.equ factor 3
引用静态数据元素必须在标签名称前面使用$
3. bss段:
命令:
- .comm:声明未初始化的数据的通用内存区域
- .lcomm:声明未初始化的数据的本地通用内存区域
这两种区域的工作情况类似,但是本地通用区域是为不会从本地汇编代码之外进行访问的数据保留的。
命令格式:.comm symbol,length ----symbol是标签,length是该内存区域的内存量
在bss段声明数据的一个好处:数据不包含在可执行程序中,即可使可执行程序的大小尽量小
传送数据元素—MOV指令
MOV指令的基本格式:movx source,destination
x可以为下面的字符:
l:用于32位的长字值
w:用于16位的字值
b:用于8位的字节值
mov指令的源和目标操作数:
- 把立即数传送到寄存器和内存
- 在寄存器之间传送数据
- 在内存和寄存器之间传送数据
在寄存器之间传送数据:
8个通用寄存器(EAX,EBX,ECX,EDX,EDI,ESI,EBP和ESP):常用于保存数据
通用寄存器可以传送给任何其它类型的寄存器,而专用寄存器(控制,调试和段寄存器)只能传送给通用寄存器
在内存和寄存器之间传送数据:
- 把数据从内存传送到寄存器 movl value,%eax
- 把数据从寄存器传送到内存 movl %ecx,value
- 使用变址的内存位置:内存位置由:基址,偏移量,数据元素的长度,具体哪个数据元素。表达格式:base_address (offset_address,index,size)所获取的数据的位置为:base_address + offset_address + index*size
例如:values:
.int 10,15,20,25
为了取出20:
movl $2, %edi
movl values(,%edi,4),%eax
数据的index从零开始数 - 使用寄存器间接寻址:寄存器还可以保存内存地址,当寄存器保存内存地址时,被称为指针,使用指针访问在内存位置中的数据称为间接寻址
- 在标签前面加上$获得数据值的内存地址,例如:movl $values, %edi将values标签的地址传送给edi
- 内存地址在寄存器中:movl %ebx, 4(%edi)
条件传送指令
CMOV指令:格式: comvx source,destination
EFLAGS | 名称 | 描述 |
---|---|---|
CF | 进位(Carry)标志 | 数学表达式产生了进位或者借位 |
OF | 溢出(Overflow)标志 | 整数值过大或则过小 |
PF | 奇偶校验(Parity)标志 | 寄存器包含数学操作造成的错误数据 |
SF | 符号(Sign)标志 | 指出结果为正还是负 |
ZF | 零(Zero)标志 | 数学操作的结果为零 |