汇编伪指令解析

2021/11/17 22:09:44

本文主要是介绍汇编伪指令解析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

伪指令说明示例

.section .data

.section .text

.globl _start

_start:

  movl $1, %eax

  movl $4, %ebx

  int $0x80

.section指示把代码划分成若干个段(section),程序被操作系统加载时,每个段被加载到不同的地址,具有不同的读写执行权限。

.data段保存程序的数据是可读写的,C程序的全局变量也属于.data段。上边的程序没定义数据所以.data是空的。

.text段保存代码,是只读和可执行的,后面那些指令都属于这个.text段。

_start是一个符号(Symbol),符号在汇编程序中代表一个地址,可以用在指令中,汇编程序经过汇编器的处理后所有的符号都被替换成它所代表的地址值。

.globl指示告诉汇编器_start这个符号要被链接器用到,所以要在目标文件的符号表中给它特殊标记。_start就像C程序的main函数一样特殊是整个程序的入口,链接器在链接时会查找目标文件中的_start符号代表的地址,把它设置为整个程序的入口地址,所以每个汇编程序都要提供一个_start符号并且用.globl声明。如果一个符号没有用.globl指示声明这个符号就不会被链接器用到。

.ascii ""插入字符串到目标文件,但不以NULL结束

.ascii "JNZ"  

//插入字节0x4A 0x4E 0x5A

.asciz ""与.ascii类似,但以NULL结束

.asciz "JNZ"

//插入字节0x4A 0x4E 0x5A 0x00

变量名 equ 数值表达式
变量名 equ <字符串>      

//可以放一句代码!!
变量名 = 数值表达式

变量定义伪指令。
equ命令不允许重复赋值,
但是“=”允许

two equ 2
thirteen =13
calldos equ <int 21h>

mov ah, 2
mov dl, 13
int 21h
//可以如下写
mov ah, two
mov dl, thirteen
calldos

X=13    //合法
X=X+5   //合法
two equal 3

 //不合法,因为已经声明过two了

.balign {alignment} {,fill} {,max}。

第一个参数alignment为一个正整数,以alignment的值的整数倍为结束地址进行对齐,以当前地址为起始地址,进行字节填充,比如当前地址为20,而alignment的值我们设定为16,那么字节填充自20开始,结束于20后第一个16的倍数地址处,即32处。

第二个参数fill即我们选定的,用来填充的数值。balign模式下为1字节,此参数可选,不标则采用默认值0。

第三个参数max也是可选项,默认值为alignment。若对齐时偏移量大于max,则不偏移。同上例,从16--32,偏移量为16,如果max我们设置为8,那么该偏移不进行。

.balign是意思是,以当前地址开始,以第一个参数为整数倍的地址为尾,1个字节1字节的填充第二个参数值(第二个参数也是1个字节的值)。

.balign 8, 0xde

解释:以当前地址开始,逐字节的往地址单元中填入0xde值,直到遇到第一个地址为8的倍数。如果当前地址(pc值)正好是8的倍数,则没有东西被写入到内存。

那么以此类推,.balignw则表示逐字(2个字节)的填充,第二个参数是2个字节的值,所以一般有这样的形式出现:

.balignw 4,0x368d

因为现在填入的内容为16位了,那就存在以下几种情况

1.当前地址没有偏移就满足了以4为倍数的地址

2.当前地址偏移了1个字节就满足了要求

3.当前地址偏移了2个字节就满足了要求

4.当然地址编移了3个字节就满足了要求

当没有偏移的时候,地址中间肯定没有办法填上信息;
当偏移1个字节的时候,地址中间空隙不够,所以填入的数值,是末定义,也就是说,填入的什么值,不清楚;
当偏移为2个字节的时候,地址中间的空隙正好填入手面的数据,所以就填上了;
当偏移为3个字节的时候,地址中间的空隙大于所要填的内容。手册上给的定义是末定义,在我的理解,其实这个未定义,是指这三个偏移的地址整体的内容是末知的。但是其中必定含有要填的2个字节,只是另一个被填充的字节内容不知道而已

所以以此类推,就知道.balignl的作用了。

.align的作用范围只限于紧跟它的那条指令或者数据

不同平台的align 指令 有两种对齐方式
第一种:
a29k,hppa, m68k, m88k, w65, sparc, and Hitachi SH, and i386 的elf 格式的目标文件,直接按字节数对齐。如下:
.align 4 //按 4 个字节的倍数对齐下一个符号,空隙默认用0 来填充
.align 4,0x90 //以4的倍数对齐地址,空隙用0x90 也就是nop 指令来填充
第二种:
For other systems, including the i386 using a.out format, and the arm and strongarm, 是按2的指数bit来对齐
.align 5 //就是2的5次方对齐,也就是4字节对齐

balignl: 4字节填充

balignw:2字节填充

balign:1个字节填充

.byte {,}插入字节到目标文件

.byte 0x55       

//插入字节: 0x55

.else与 .if 和 .endif 配合使用
.end标志汇编文件结束,汇编器不再读后面的内容
.endif与.if 配合使用
.endm标志宏定义结束,与.macro配合使用
.endr结束一个loop,与.rept 和 .irp 配合使用
.err汇编时如遇到.err,则停止编译
.exitm中途退出宏定义
.equ 或 =设置一个符号的值

.equ adams, (5 * 8) + 2  

@ set adams to 42

.set adams, 0x2A 

@ set adams to 42

adams = 0b00101010    @ set adams to 42

.global标识symbol被程序的其它模块(汇编或C)访问

.global _my_test_count  

@它可被其它模块R/W

.hword {,}插入16位(半字)值到目标文件

.hword 0xAA55, 12345

@ 插入字节 0x55 0xAA 0x39 0x30

.2byte

.2byte 0x55AA, -1

@插入字节 0xAA 0x55 0xFF 0xFF

.if与 .endif 配合使用
.ifdef与 .endif 配合使用
.ifndef与 .endif 配合使用
.include ""

与C的#include类似

.irp

Repeats a block of code, once for each value

 in the value list. Mark the end of the block 

using a .endr directive. In the repeated code block,

 use to substitute the associated 

value in the value list.

.macro

定义一个名为name的汇编宏,它有N个参数,

且必须以.endm结束。

.macro SHIFTLEFT a, b

    .if b < 0

        MOV a, a, ASR #-b

       .exitm

    .endif

    MOV a, a, LSL #b

.endm

.section

开始一个新的section, section_name可为:

   .text: 代码段

   .data: 已初始化的数据段

   .bss: 未初始化的数据段

flags可为:

   a allowable section

   w writable section

   x executable section

.section .text, “x”
.set设置变化的值,与.equ一样

.set adams, 0x2A         

@ set adams to 42

.space预留给定字节空间,并设置为0或fill_byte.space 0x400,0
.word插入32位字列表到目标文件

.word 0xDEADBEEF  

@inserts the bytes 0xEF 0xBE 0xAD 0xDE

.4byte -42        

@ inserts the bytes 0xD6 0xFF 0xFF 0xFF        

 @ Least Significant Byte (LSB) ordering assumed

.rept

重复执行代码块number_of_times次,与C中for类似,以endr结束

.req寄存器重新命名acc .req r0
@代码行中的注释符号arm特殊
#整行注释符号
;语句分离符号
.arm汇编使用ARM指令
.code16汇编使用Thumb指令
.code32汇编使用ARM指令
.force_thumb强制使用thumb模式,即使不支持
.thumb_funcMark entry point as thumb coded (force bx entry)
.ltorgStart a new literal pool(文字池:嵌入在代码中的用以存放常数的区域)
.data标识把随后的语句放入目标文件数据段
.text标识把随后的语句放入目标文件的代码段
.extern symbol从其它模块引入符号,类似C中的extern
.skip expression

 在目标文件中skip expression指定的字节数

buffer: .skip 512 @Buffer of 512 bytes, uninitialised

x86

.code16

.code32

以下代码汇编生成16位代码

以下代码汇编生成32位代码



这篇关于汇编伪指令解析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程