32位80x86汇编语言ptr指令学习笔记
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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@