栈中的数据是如何访问的?

chimenghuanzhe 2018-03-13 05:29:26
面试的时候被问到,数组a[10]是存放在堆中还是栈中,我下意识的就回答,是在栈中。可是面试官一脸诡异的问我肯定吗?犹豫了一下,点头肯定。

然而回来后自己用电脑试了一下,反汇编,如图
#include <iostream>
using namespace std;
int main()
{
char buf[10]={11,12,13,};
buf[0]=3;
buf[2]=5;
char *f=NULL;
f=(char*)malloc(15);
f[1]=9;
free(f);
return 0;
}
反汇编代码:

char buf[10]={11,12,13,};
01394388 mov byte ptr [buf],0Bh
char buf[10]={11,12,13,};
0139438C mov byte ptr [ebp-13h],0Ch
01394390 mov byte ptr [ebp-12h],0Dh
01394394 xor eax,eax
01394396 mov dword ptr [ebp-11h],eax
01394399 mov word ptr [ebp-0Dh],ax
0139439D mov byte ptr [ebp-0Bh],al
buf[0]=3;
013943A0 mov eax,1
013943A5 imul eax,eax,0
013943A8 mov byte ptr buf[eax],3
buf[2]=5;
013943AD mov eax,1
013943B2 shl eax,1
013943B4 mov byte ptr buf[eax],5
char *f=NULL;
013943B9 mov dword ptr [f],0
f=(char*)malloc(15);
013943C0 mov esi,esp
013943C2 push 0Fh
013943C4 call dword ptr ds:[13A03BCh]
013943CA add esp,4
013943CD cmp esi,esp
013943CF call __RTC_CheckEsp (013912D5h)
013943D4 mov dword ptr [f],eax
f[1]=9;
013943D7 mov eax,1
013943DC shl eax,0
013943DF mov ecx,dword ptr [f]
013943E2 mov byte ptr [ecx+eax],9


不是说放在栈中吗?栈中的数据访问不是用push和pop吗,为什么可以直接 这样“ mov byte ptr buf[eax],3 ” 用地址就可以访问,这样一来和堆有啥区别?还是说这个栈和数据结构中栈 完全两码事?

哪本书或者网址讲了这方面的东西,能不能说一下书名或者给个链接也行。
...全文
1165 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
Code_learner_ 2020-04-26
  • 打赏
  • 举报
回复
对程序它是我们定义的栈空间,但是对CPU也只是一块普通内存而已
mk_lucifer 2018-03-14
  • 打赏
  • 举报
回复
栈也是普通内存,普通寻址方法就可以,Pop和Push是两个特殊指令,多因为一些算法需要,(a*b)+(c*d) ,一种 a*b的结果就必须放入栈中,此时是用Push, 而单纯的 int a[10] 直接栈指针+40或-40就OK了,你总不能Push 10次0吧,这也不科学。。。
mk_lucifer 2018-03-14
  • 打赏
  • 举报
回复
Push和Pop可以移动栈指针,但不代表只能靠这两个方法移动,Push和Pop移动的长度是固定的,如果要大长度模移动直接修改SP就可以了。。。Push和Pop多用于运算中推入数据或弹出数据,通常用于算法,比如一个表达式运算中的中间数据。。。。单纯的开辟栈控件并不赋值,就不会用这俩指令,直接移动SP就可以了。。。
赵4老师 2018-03-14
  • 打赏
  • 举报
回复
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
zhangyiant 2018-03-13
  • 打赏
  • 举报
回复
在栈中,不一定需要push, pop指令。
mstlq 2018-03-13
  • 打赏
  • 举报
回复
不一定要push和pop,直接移动栈顶指针也是可以的……
paschen 版主 2018-03-13
  • 打赏
  • 举报
回复
上面已经说了,在栈上开辟空间未必需要使用push,直接移动栈顶指针即可,函数使用的就是这种方式
真相重于对错 2018-03-13
  • 打赏
  • 举报
回复
堆你必须new delete
chimenghuanzhe 2018-03-13
  • 打赏
  • 举报
回复
引用 3 楼 hdt 的回复:
bpx是基址寄存器代表栈底,sp寄存器是栈顶,push pop只对栈顶操作,但是要访问栈顶和栈底之间数据,就用BP-数值 来访问
我也是刚才找到了一个解释,访问栈也可以不用pop和push,http://blog.csdn.net/fengyunjh6/article/details/9048613,可以直接用栈底的指针加偏移量来访问。但是这样一来和堆有什么区别?
真相重于对错 2018-03-13
  • 打赏
  • 举报
回复
bpx是基址寄存器代表栈底,sp寄存器是栈顶,push pop只对栈顶操作,但是要访问栈顶和栈底之间数据,就用BP-数值 来访问
真相重于对错 2018-03-13
  • 打赏
  • 举报
回复
如果定义了一个以上的局部变量,只通过pop push操作栈顶肯定是不够的
chimenghuanzhe 2018-03-13
  • 打赏
  • 举报
回复
按我的理解 如果用push操作,比如 b[1]=3;应该先把b[0] ,b[1] 弹出来,然后push 3, push b[0],可是这样又怪怪的,而且反汇编的结果不是这样访问的,是直接通过地址访问的。所以搞不懂。
paschen 版主 2018-03-13
  • 打赏
  • 举报
回复
局部变量都是在栈上,push、pop指令会自动调整esp的值,也可以直接移动esp指针,函数调用时就已经移动好了esp指针,也就是局部变量所需要的空间已经有了,之后赋值只是MOV到对应的地址

64,639

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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