汇编语言实现指针操作

发表于:2015年2月11日 19:30  分类:assembly 1,210次浏览

在C语言中,强大的指针操作大大增强了程序的灵活性,我们可以直接操作内存中的数据进行运算,但是指针又是很难理解的,我最初学习C语言的时候,总是被两个问题所困扰:
1、既然指针是一个变量,那么它在内存的存在形式如何?
2、指针保存了变量的地址,不同的变量类型对于了不同的指针类型,这种不同的指针类型在内存中是如何体现的呢?
为了理解这两个问题,我用汇编语言实现了简单的指针操作,分析指针在内存中的实际存在形式。

使用win32汇编语言,编写如下代码:

TITLE Pointers (a.asm)
.386
.model flat,stdcall
ExitProcess PROTO, dwExitCode:DWORD
.data
arrayB BYTE 10H,20H,30H
arrayW WORD 1,2,3
arrayD DWORD 4,5,6
ptr1 DWORD arrayB
ptr2 DWORD arrayW
ptr3 DWORD arrayD
.code
main PROC
	mov esi,ptr1
	mov al,[esi]
	mov esi,ptr2
	mov ax,[esi]
	mov esi,ptr3
	mov eax,[esi]
	INVOKE ExitProcess,0
main ENDP
END main

arrayB、arrayW、arrayD定义了三个数组,数组中的元素大小分别是1字节、2字节、4字节,ptr1、ptr2、ptr3分别是指向这三个数组的指针变量,保存了三个数组的首地址。
使用visual studio的集成开发环境调试该程序,调试代码如下:

--- D:\irvine\bat\a.asm -------------------------------------------
	mov esi,ptr1
00EF1010  mov         esi,dword ptr ds:[0EF4015h]  
	mov al,[esi]
00EF1016  mov         al,byte ptr [esi]  
	mov esi,ptr2
00EF1018  mov         esi,dword ptr ds:[0EF4019h]  
	mov ax,[esi]
00EF101E  mov         ax,word ptr [esi]  
	mov esi,ptr3
00EF1021  mov         esi,dword ptr ds:[0EF401Dh]  
	mov eax,[esi]
00EF1027  mov         eax,dword ptr [esi]  
	INVOKE ExitProcess,0
00EF1029  push        0  
00EF102B  call        _ExitProcess@4 (0EF1038h)  
--------------------------------------------------------------------

 
1、既然指针是一个变量,那么它在内存的存在形式如何?
ptr1、ptr2、ptr3是三个变量,存在于内存当中,从上面的调试信息来看,ptr1、ptr2、ptr3连续存储在0EF4015h开始的内存中,查看该部分内存:

0x00EF4015  00 40 ef 00 03 40 ef 00 09 40 ef 00 00 00 00 00

因为win32保护模式中寄存器为32位,所以地址的长度为32位,既然指针保存了变量的地址,那么指针变量在内存中的长度就应该为32位(4个字节),以上三个指针变量在内存中的存在形式为:ptr1=00ef4000、ptr2=00ef4003、ptr3=00ef4009,内存中00ef4000开始的位置存放了数组:

0x00EF4000  10 20 30 01 00 02 00 03 00 04 00 00 00 05 00 00 00 06 00 00 00

 
2、指针保存了变量的地址,不同的变量类型对于了不同的指针类型,这种不同的指针类型在内存中是如何体现的呢?
上面已经分析了指针变量在内存中的实际存在形式,指针变量都是一样的长度(4个字节),可是如何体现指针的类型呢?在C语言中有指向int的指针、指向char的指针、指向long的指针,上面三个指针变量在内存中并没有体现这一点区别。
观察程序代码本身,可以看见每一条mov指令都是指明了数据的长度。编译器在编译代码的时候,就会为指向不同类型数据的指针操作添加byte ptr、word ptr、dword ptr等内容,这就体现了不同指针类型间的区别。

发表评论

电子邮件地址不会被公开。 必填项已用*标注