当前位置:软件学习 > 其它软件 >>

AT&T 汇编数据传送

注:以下内容为学习笔记,多数是从书本、资料中得来,只为加深印象,及日后参考。然而本人表达能力较差,写的不好。因非翻译、非转载,只好选原创,但多数乃摘抄,实为惭愧。但若能帮助一二访客,幸甚!
 
 
 
一.定义数据
1.数据段
程序的数据段是最常见的定义数据元素的位置。使用.data命令声明数据段,.rodata中定义的数据只能按照只读模式访问。
在数据段中定义数据元素需要两个语句:一个标签和一个命令,标签用作引用数据元素所使用的标记,类似与C中的变量名,另外需要一个汇编命令定义为数据元素保留的字节数:
------------------------------------------------------
命令 数据类型
----------------------------------------------------
.ascii 文本字符串
.asciz 以空字符结尾的文本字符串
.byte 字节值
.double 双精度浮点数
.float 单精度浮点数
.int 32位整数
.long 32位整数(同.int)
.octa 16字节整数
.quad 8字节整数
.short 16位整数
.single 单精度浮点数(同.float)
-------------------------------------------------------
例子:
output:
.ascii  "Hello AT&T\n"
这个代码片段会留出11字节的内存,把定义的字符串顺序放到内存字节中,且把标签output赋值为第一个字节地址。
可以在一行中定义多个值:
sizes:
.long 100, 101, 102, 103
上面的代码把4个长整数(4字节)按顺序放到内存中,可按相对地址访问每个值,如访问内存sizes+8访问102.
 
2.定义静态符号
.equ命令用于把常量值设置为可以在为本段中使用的符号:
.equ LINUX_SYS_CALL_WRITE  4
引用静态数据元素:
movl $LINUX_SYS_CALL_WRITE, %eax
 
3.BSS段
在bss段中定义数据无需声明特定的数据类型,只要声明为所需目的保留的原始部分即可。
上句感觉汉语版翻译的不太明白,英文原句:
Instead of declaring specific data types, you just declare raw segment of memory that are reserved fo whatever purpose you need them for.
GNU 汇编器使用两个命令声明缓冲区:
--------------------------------------------------------------------
命令 描述
-------------------------------------------------------------
.comm 声明未初始化的数据的通用内存区域
.lcomm 声明未初始化的数据的本地通用内存区域
--------------------------------------------------------------------
本地通用内存区域是为不会从本地汇编代码之外进行访问的数据保留的。
命令格式:
.comm symbol,  length
例如:
.section .bss
.lcomm buffer, 100
 
二.数据传送
1.MOV 指令
格式:
mov* src,  dst
GNU汇编器要求MOV指定传送的数据的长度mov*中的*:
---------------------------------------------------
l 32位
w 16位
b 8位
---------------------------------------------------
注:未包含字符串传递指令MOVS等
src、dst的值可以是内存地址、存储在内存中的数据值、指令语句中定义的数据值、寄存器。
 
2.把立即数传送到寄存器、内存
立即数前面要加$符号,寄存器前面要加%符号
1)立即数传送到寄存器:
movl $0x80,  %eax
2) 立即数传送到指定内存地址
若数据段中有:
.section .data
height:
.int 10
则可用下面的方法将立即数传递到height表示的内存地址:
mvol $0x100,  height
注:标签表示的是内存地址
 
3.在寄存器之间传送数据
8个通用寄存器:EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP,这些寄存器中的值可以传送给可用的任何其他类型的寄存器。
专用寄存器(控制、调试、段寄存器)的内容只能传送给通用寄存器,或从通用寄存器接收内容。
movl %eax,  %ebx
movw %ax,  %bx
 
4.在内存和寄存器之间传送数据
1)内存 -> 寄存器
movl value, %eax
该指令将value指定的内存开始的32位数据传送给eax。若数据长度小于4自己,则需使用movw或movb。
测试代码:
 
 
[plain] 
<span style="font-family:SimSun;font-size:10px;"># 测试从内存传送数据到寄存器  
  
.section .data  
value:  
    .byte   0x01, 0x02, 0x03, 0x04  
  
.section .text  
.global _start  
  
_start:  
    nop  
    xorl    %ecx,   %ecx  
    movl    value,  %ecx  
  
    xorl    %edx,   %edx  
    movw    value,  %dx  
  
    xorl    %ebx,   %ebx  
    movb    value,  %bl  
  
    movl    $1,     %eax  
    movl    $0,     %ebx  
    int     $0x80  
</span>  
makefile:
[plain]   
<span style="font-family:SimSun;font-size:10px;">all: mem_to_reg  
mem_to_reg: mem_to_reg.o  
    ld -o $@ $<  
mem_to_reg.o: mem_to_reg.s  
    as -gstabs -o $@ $<</span>  
调试及结果:
liury@liury-laptop:~/program/asm/move_data$ make
as -gstabs -o mem_to_reg.o mem_to_reg.s
ld -o mem_to_reg mem_to_reg.o
liury@liury-laptop:~/program/asm/move_data$ ls
makefile  mem_to_reg  mem_to_reg.o  mem_to_reg.s
liury@liury-laptop:~/program/asm/move_data$ gdb ./mem_to_reg 
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/liury/program/asm/move_data/mem_to_reg...done.
(gdb) l
1 # 测试从内存传送数据到寄存器
3 .section .data
4 value:
5 .byte  0x01, 0x02, 0x03, 0x04
7 .section .text
8 .global  _start
10 _start:
(gdb) b *_start+1
Breakpoint 1 at 0x8048075: file mem_to_reg.s, line 12.
(gdb) r
Starting program: /home/liury/program/asm/move_data/mem_to_reg 
 
 
Breakpoint 1, _start () at mem_to_reg.s:12
12 xorl  %ecx, %ecx
(gdb) n
13 movl  value, %ecx
(gdb) print /x $ecx
$1 = 0x0
(gdb) n
15 xorl  %edx, %edx
(gdb) print /x $ecx
$2 = 0x4030201
(gdb) n
16 movw  value, %dx
(gdb) print /x $edx
$3 = 0x0
(gdb) n
18 xorl  %ebx, %ebx
(gdb) print /x $edx
$4 = 0x201
(gdb) n
19 movb  value, %bl
(gdb) print /x $eb
补充:软件开发 , 其他 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,