下面两个程序有区别吗?

iwantnon 2010-03-17 10:19:40
//程序1
int*a=new int[2];
a[0]=100;
a[1]=200;
int i=1;
int r;
__asm{
mov ebx,i
mov eax,a+4
mov r,eax
}
cout<<r<<endl;

//程序2
int a[]={100,200};
int i=1;
int r;
__asm{
mov ebx,i
mov eax,a[ebx*4]
mov r,eax
}
cout<<r<<endl;

程序2能输出正确结果200,而程序1结果不对,为什么呢?难道动态申请的数组无法间接寻址?
...全文
85 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
iwantnon 2010-03-20
  • 打赏
  • 举报
回复
谢谢各位,结帖。
zara 2010-03-19
  • 打赏
  • 举报
回复
看最后生成的实际指令哎,其实是一样的。
iwantnon 2010-03-18
  • 打赏
  • 举报
回复
恩,谢谢各位,我试过了,如楼上各位所部,用下面方法可以:
__asm{
mov ebx,i
mov eax,a
lea eax,[eax][ebx*4]
mov eax,[eax]
mov r,eax
}
另外,我又试了一下用:
__asm{
mov ebx,i
mov eax,a
lea eax,[eax+ebx*4]
mov eax,[eax]
mov r,eax
}
也是可以的。
我还想最后再问一下就是:
以上两种方法在效率上相同吗?
zara 2010-03-18
  • 打赏
  • 举报
回复
看下生成的 exe 中这个部分的代码不就可以了?
mov eax, a[ebx*4] 形成的最后代码是 MOV EAX,DWORD PTR SS:[EBP-4+EBX*4],其中 EBP-4 是 a 这个指针局部变量在栈中的位置。所以,性质和上面并没有本质不同。
再看对 a[?] 赋值的语句生成的指令:
MOV ECX,DWORD PTR SS:[EBP-4]
MOV DWORD PTR DS:[ECX],64
MOV EDX,DWORD PTR SS:[EBP-4]
MOV DWORD PTR DS:[EDX+4],0C8
所以,要对 a[] 数组中的元素进行引用,是不能简单地用一条指令实现的。需要自己将下标转换为数组内偏移量,再和 *a 这个指针相加,才能得到元素在内存中的实际地址,进而对其进行操作。
所以, 1. 的功能,简单地也可以写成:
__asm{
mov ebx,i
mov eax,a
mov eax,[eax][ebx*4]
mov r,eax
}

对于 int a[2]; 这样预分配在栈中的局部变量性质的数组,由于其各个成员都是在栈中且其位置是预知的,所以,即便是访问不定下标的成员,也可以一个指令便能完成:
mov eax, [ebp-??][ebx*4]
; [ebp-??] 为数组在栈中的起始地址;ebx 为要访问的成员的下标;4 为成员单位字节长度
zara 2010-03-17
  • 打赏
  • 举报
回复
a+4 好像也不是 a[ebx*(+?)4*4],而是 [a]+4*4
如果要访问 i 指定的下标数组元素的话,可以这样吧:
__asm{
mov ebx,i
mov eax,a
lea eax,[eax][ebx*4]
mov eax,[eax]
mov r,eax
}
guyuehun1 2010-03-17
  • 打赏
  • 举报
回复
是这样的, int*a=new int[2];这里定义的 a 是一个int类型的指针, a+1表示的是移动一个int单位. 所以a+4这句代码相当于a[ebx*4*4],里面的数据已经不是200了.
iwantnon 2010-03-17
  • 打赏
  • 举报
回复
我晕!程序1贴错了,应该是:
//程序1
int*a=new int[2];
a[0]=100;
a[1]=200;
int i=1;
int r;
__asm{
mov ebx,i
mov eax,a[ebx*4]
mov r,eax
}
cout<<r<<endl;
程序2跟原来一样,仍是:
//程序2
int a[]={100,200};
int i=1;
int r;
__asm{
mov ebx,i
mov eax,a[ebx*4]
mov r,eax
}
cout<<r<<endl;
然后麻烦各位再来解答一下!
zara 2010-03-17
  • 打赏
  • 举报
回复
1. 中的 mov eax, a+4 给 eax 的是地址,下面再给 r 的还是地址,不是值。试试改成:
__asm{
mov ebx,i
mov eax,a+4
mov eax,[eax]
mov r,eax
}

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧