AT&T汇编移动数据

本文详细介绍了AT&T汇编语言中的数据定义,包括数据段、静态符号和bss段的使用。接着讲解了如何移动数据,如移动命令、索引访问内存和寄存器间接地址访问,并探讨了条件mov指令。此外,还讨论了栈的工作原理,包括入栈和出栈操作及其在数据交换中的应用。
摘要由CSDN通过智能技术生成

定义数据

数据段

.data 和 .rodata
数据类型:
* ascii 字符串
* asciz 0结束的字符串
* byte 字节值
* double 双精度浮点数
* float 单精度浮点数
* int 32位整数
* long 32位整数
* octa 16位整数
* quad 8位整数
* short 16位整数
* single 单精度浮点数
示例:

.section .data
msg:
	.ascii "this is a test message"
factors:
	.double 37.45, 45.33, 12.30
height:
	.int 54
length:
	.int 62,35,47
定义静态符号

示例:

.equ factor, 3
.equ LINUX_SYS_CALL, 0x80
movl $LINUX_SYS_CALL, %eax
bss 段

命令:
* comm 声明一段未初始化的内存区域
* .lcomm 生命一段本地的未初始化的内存区域(不能被其他文件访问)
格式:
.comm sysbol, length
示例:

	.section .bss
	.lcomm buffer, 10000

移动数据

移动命令
  • 格式:
    movx source, destination
    x标识操作的位
    l 32位
    w 16位
    b 8位
  • 规则:
    • 立即数到一般寄存器
    • 立即数到内存单元
    • 一般寄存器到另外一个一般寄存器
    • 一般寄存器到段寄存器
    • 段寄存器到一般寄存器
    • 一般寄存器到段寄存器
    • 控制寄存器到一般寄存器
    • 一般寄存器到调试寄存器
    • 调试寄存器到一般寄存器
    • 内存单元到一般寄存器
    • 内存单元到段寄存器
    • 一般寄存器到内存单元
    • 段寄存器到内存单元
  • 示例:
#movtest2.s - An example of moving register data to memory
.section .data
	value:
		.int 1
.section .text
.globl _start
	_start:
		nop
		movl $100, %eax
		movl %eax, value
		movl $1, %eax
		movl $0, %ebx
		int $0x80
  • 调试
    • as -o movtest2.o -gstabs movtest2.s
    • ld -o movtest2 movtest.o
    • gdb -q movtest2
    • break *_start+1
    • run
    • x/d &value
    • s
    • s
    • x/d &value
使用索引访问内存
  • 格式:
    base_address(offset_address, index, size)
  • 示例:
# movtest3.s - Another example of using indexd memory locations
.section .data
output:
	.asciz "The value is %d\n"
values:
	.int 10, 15, 20,25,30,35,40,45,50,55,60
.section .text
.globl _start
_start:
	nop
	movl $0, %edi
loop:
	movl values(, %edi, 4), %eax
	pushl %eax
	pushl $output
	call printf
	addl $8, %esp
	inc %edi
	cmpl $11, %edi
	jne loop
	movl $0, %ebx
	movl $1, %eax
	int $0x80
  • 执行
    • as -o movtest3.o movtest3.s
    • ld -dynamic-linker /lib/ld-linux.so.2 -lc -o movtest3 movtest3.o
使用寄存器间接地址访问
  • 格式:
    • mov $values, %edi 将values的地址存入edi
    • mov %ebx, (%edi) 将ebx的值存入edi所存的内存中
  • 示例:
#movtest4.s - An example of indirect addressing
.section .data
values:
	.int 10, 15, 20, 25, 30, 35, 40, 45, 55, 60
.section .text
.globl _start
_start:
	nop
	movl values, %eax
	movl $values, %edi
	movl $100, 4(%edi)
	movl $1, %edi
	movl values(, %edi, 4), %ebx
	movl $1, %eax
	int $0x80

条件mov指令

  • 格式:
    cmovx source, destination
    x代表跳转条件的字符
    * CF 进位标识
    * OF 溢出标识
    * PF 奇偶标识
    * SF 正负标识
    * ZF 零标识

无符号数跳转

指令描述符号位
CMOVA/CMOVNBE大于或者不小于等于(CF or ZF) = 0
CMOVAE/CMOVNB大于等于或者不小于CF=0
CMOVNC没有进位CF=0
CMOVVB/CMOVNAE小于CF=1
CMOVC有进位CF=1
CMOVBE/CMOVNA不大于(CF or ZF) = 1
CMOVE/CMOVZ等于ZF=1
CMOVNE/CMOVNZ不等于ZF=0
CMOVP/CMOVPE字节1为偶数个PF=1
CMOVNP/CMOVPO字节1为奇数PF=0

有符号数跳转

指令描述符号位
CMOVGE/CMOVNL大于等于(SF xor OF)=0
CMOVL/CMOVNGE小于(SF xor OF) = 1
CMOVLE/VMOVNG小于等于((SF xor OF) or ZF) = 1
CMOVO溢出OF=1
CMOVNO没有溢出OF=0
CMOVS正数SF=1
CMOVNS非正SF=0
使用CMOV指令
#cmovtest.s - An example of the CMOV instructions
.section .data
output:
	.asciz "The largest value is %d\n"
valuse:
	.int 105, 235, 61, 315, 134, 221, 53, 145, 117, 5
.section .text
.globl _start
_start:
	nop
	movl values, %ebx
	movl $1, %edi
loop:
	movl values(, %edi, 4), %eax
	cmp %ebx, %eax
	cmova %eax, %ebx
	inc %edi
	cmp $10, %edi
	jne loop
	pushl %ebx
	pushl $output
	call printf
	addl $8, %esp
	pushl $0
	call exit

交换数据

数据交换指令
* XCHG 交换两个寄存器或者一个寄存器一个内存单元
* BSWAP 反转32为寄存器的字节顺序
* XADD 交换两个数并将和存储在目的操作数
* CMPXCHG 比较交换
* CMPXCHG8B 比较交换两个64位数
使用数据交换指令
# bubble.s - An example of the XCHG instruction
.section .data
values:
	.int 105, 235, 61, 315, 134, 221, 53, 145, 117, 5
.section .text
.globl _start
	_start:
		movl $values, %esi
		movl $9, %ecx
		movl $9, %ebx
	loop:
		movl (%esi), %eax
		cmp %eax, 4(%esi)
		jge skip
		xchg %eax, 4(%esi)
		movl %eax, (%esi)
	skip:
		add $4, %esi
		dec %ebx
		jnz loop
		dec %ecx
		jz end
		movl $values, %esi
		mov %ecx, %ebx
		jmp loop
	end:
		movl $1, %eax
		movl $0, %ebx
		int $0x80 

栈是如何工作的
出栈和入栈

*语法:
pushx source
pop destination

  • 将所有的寄存器入栈出栈
    • PUSHA/POPA 将所有的16位一般寄存器入栈/出栈
    • PUSHAD/POPAD 将所有的32位寄存器入栈/出栈
    • PUSHF/POPF 将16位的符号寄存器入栈/出栈
    • PUSHFD/POPFD 将32位的符号寄存器入栈/出栈
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值