32位80x86汇编语言ptr指令学习笔记

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

阅读反汇编后的汇编程序挺麻烦,尤其是在c语言程序的子函数参数中有数组参数,同时当子函数里有循环操作时,反汇编后的代码中频繁出现ptr指令操作。该指令的用法十分灵活,有时候读入(或写入)的是某内存地址,有时候读入(写入)的是某内存地址中存储的值,初学时总感觉很迷惑,分不清什么时候读内存地址,什么时候读内存地址中值,参考相关文献和书籍后作如下总结。

例如一段简单的C语言程序:

int mywork(int a[9], int b[9], int c[9])

{

int i;

for ( i=0; i<9; i++)

c[i] =a[i] +b[i];

}

这段代码debug版反汇编后代码很简单,但是里面有许多小细节值得推敲。

int mywork(int a[9], int b[9], int c[9]) ;原c代码

… … ;这里为开始调用函数时当前寄存器数据保存

for ( i = 0 ; i < 9 ; i ++)

mov dword ptr [i], 0;这里为i初始化,值为0

jmp mywork+xx1h ;进入循环体内部

mov eax, dword ptr [i];

add eax, 1

mov dword ptr [i], eax

mywork+xx1h:cmp dword ptr [i], 9

jge mywork+xx2h ;如果i等于或大于9,跳出循环

c[i] =a[i] +b[i];

mov eax, dowrd ptr [i] ;读入参数i

mov ecx, dword ptr [a] ;这里是读入参数数组a的首地址

mov edx, dword ptr [b] ;这里是读入参数数组b的首地址

mov eax, dword ptr [ecx + eax*4] ;读入a

add eax, dword ptr [edx +eax*4] ; eax = a[i]+b[i]

mov edi, dword ptr [c] ;这里是读入参数数组c的首地址

mov dword ptr [edi+ eax*4], eax ;这里保存计算结果,c[i]= a[i]+b[i]

inc eax

jmp mywork+xx1h

mywork+xx2h: … … ;一些数据恢复操作,主要是出栈等

ret

文中用红色标记处两处涉及ptr指令的地方。

第一处为mov eax, dword ptr [i]

本条mov指令的结果是将变量i的值读入到eax寄存器中,至于从i变量存储地址处读取几个字节,由dword修饰符指定(4个字节)。

第二处为mov ecx, dword ptr [a]

这里表示将参数数组a的首地址读入到ecx寄存器中。

同样两个mov 寄存器, dword ptr [变量]操作,为何第一个寄存器eax读入数值,而第二个ecx寄存器读入的为地址呢?

ptr指令会指定并修改当前已分配内存地址的标记,因为i为c语言子函数mywork中定义的int变量,而非外部传入的参数,从而在执行子函数的汇编程序中变量i的值就是保存在dword ptr [i]返回的内存地址中,占用4个字节,所以mov eax, dword ptr [i]指令将源操作数指定的地址中数据(即int变量i的值)读入到eax寄存器中;而第二处中由于数组a的首地址是作为参数传送到mywork中的,在调用mywork前,3个数组参数a、b、c的首地址依次按照c、b、a的顺序被push入栈,并且传递给子函数,因此dword ptr [a]表示数组a作为参数传递给子函数的值,即其起始首地址,并非a[0]的值,从而mov ecx, dword ptr [a]后的结果是把数组a的首地址保存在了ecx中,而非a[0]的值

第一次发读书笔记,如果写的有误请大家指正:)

苏清华,2011.6.28

联系邮箱:suqinghua4587@

相关文档
最新文档