X86 Assemble指令--offset
2018-09-05 本文已影响82人
None_Ling
offset的作用
offset
是一条伪指令,在编译的过程中,编译器会将该伪指令进行计算,并且替换成标号/变量的地址偏移量
基础知识
在数据段中,通过使用db
,dw
,dd
来定义该变量存放数据的大小。
db
: define byte,定义一个字节
dw
: define word,定义一个字,两个字节
dd
: define double word,定义两个字,四个字节
而字符串最好使用db来定义,因为字符都是使用ASCII来定义的,而每一个字符都只占一个字节。而使用dw、dd来定义的话,由于X86是Little Endian排序,所以在内存中的字符的排序会错乱
dup
伪指令定义了在编译时,会将dup
定义的数据对连续长度的内存空间进行填充。
举例
data segment
// 定义长度为4*16=64个字节(长度为40H)的数组,并且以1进行填充
data1 db 40h dup(1)
// 定义从data2单元开始,连续存放5,6,8,100,共占4个字节地址,每一个单元占一个字节
data2 db 5,6,8,100
// 定义从data3单元开始,连续存放7,287,共占4个字节,每个单元占一个字(两个字节)
data3 dw 7,287
// 定义一个字符串,字符串中每一个字符都占一个字节
data_string db 'hello world'
data ends
以上定义了数据段,并且在数据段中有一个变量data1
长度为64个字节的数组。
mov eax,offset data1;
上述汇编指令,在编译的时候会对offset
伪指令进行解释。
假如data1
的偏移量为0x400H
,那么在编译器编译过后的二进制文件中,该指令就会变成:
mov eax,0x400H;
同样,offset
伪指令对于代码段中的标号也是有同样的效果。
assume cs:codesg
codesg segment
start:mov ax,offset start ;相当于mov ax,0
s:mov ax,offset s ;相当于mov ax,3
codesg ends
end start
在编译过后,上述指令就会变成
assume cs:codesg
codesg segment
start:mov ax,0;
s:mov ax,3;
codesg ends
end start
因为代码段的偏移量是从0开始的,并且mov ax,0
指令占3个字节,所以标号s
的偏移量就是3
注意
后续还需要测试一下当DS段的基址改变时,offset
所编译出来的值是否有区别。