欢迎想深入学习C的进来讨论图片
今天学了调试,如图,至少看到了esp:网上的解释是:
esp(32位)/rsp(64位):
栈顶指针,指向栈的顶部
这里看到的是 a,b,c
它们之间,间隔的是距离是:0x14 0x18 0x 1c
从中可以看出,都是4的距离.
不知道是不是4字节的意思:
0000 0000 0x14
0000 0000
0000 0000
0000 0000
0000 0000 0x18
这么远的意思.
如果是,那么,就学到了 sizeof(a)==4 为真. 本帖最后由 jackz007 于 2022-9-16 14:49 编辑
可以看得出来,你这个是 32 位的程序。
对于函数的局部变量 a,b,c 而言,它们会在运行时从堆栈动态取得存储空间,也就是说,这些变量只有在函数被调用的时候才会临时产生,如果它们是 int 或 float 型变量,那么,每个变量均占用 4 个字节,变量 a、b、c 实际上就是这 3 个变量所占用内存空间的映射。 嗯,谢谢楼上确认。
0x401326开始,也是变化为以下
0x40132e
0x401336
也是4的距离:单位是字节吗?
1字节==8个位吗?
32位长度==4字节==一个int占用的内存长度 还都是用movl的方式变化的等距离 本帖最后由 jackz007 于 2022-9-16 15:26 编辑
howzyao 发表于 2022-9-16 14:48
嗯,谢谢楼上确认。
0x401326开始,也是变化为以下
0x40132e
0x40131e sub $0x20 , %esp <-- 在堆栈中预留出 0x20 个字节,供函数的各种局部变量使用
0x401321 call 0x41eb40 <__main> <-- 你应该单步跟踪进入这个函数(0x41eb40 ),然后才能看到你写的代码
本帖最后由 jackz007 于 2022-9-16 15:44 编辑
howzyao 发表于 2022-9-16 14:50
还都是用movl的方式变化的等距离
我也写了一个和你一模一样的代码,这是在我这边用调试器看到的代码样子
00401350/$55 push ebp
00401351|.89E5 mov ebp, esp
00401353|.83E4 F0 and esp, FFFFFFF0
00401356|.83EC 20 sub esp, 20 ; 在堆栈中开辟出 0x20 字节空间供局部变量使用
00401359|.E8 F2050000 call 00401950
0040135E|.C74424 1C 09000000 mov dword ptr , 9 ; <--- a = 9
00401366|.C74424 18 09000000 mov dword ptr , 9 ; <--- b = 9
0040136E|.C74424 14 00000000 mov dword ptr , 0 ; <--- c = 0
00401376|.8B5424 1C mov edx, dword ptr ; <--- edx = a
0040137A|.8B4424 18 mov eax, dword ptr ; <--- eax = b
0040137E|.01D0 add eax, edx ; eax = b + a
00401380|.894424 14 mov dword ptr , eax ; <--- c = eax
00401384|.C70424 24304000 mov dword ptr , 00403024 ; |ASCII "pause"
0040138B|.E8 30080000 call <jmp.&msvcrt.system> ; \system
00401390|.B8 00000000 mov eax, 0 ; eax = 0 就是 return 0 中的那个 0
00401395|.C9 leave
00401396\.C3 retn
00401397 90 nop
你的反汇编代码采用了 AT&T 风格,我这个采用的是 Intel 风格,二者虽然在指令文本形式上存在不同,但是,机器指令本身并无本质的差别。
用Vc6.0调试看看更直观! sub $0x20 , %esp
预留,美元符 %esp栈顶指针的格式。
0x20 就是2000 0000 一个字节的边度十进制数,就是全部加起来1248 16 32 64 128
都是0,就是128*2=256字节==0x20
放入了这个栈内存,这个栈内存叫做esp,它是栈顶,也是个指针,指向顶部之下的255字节的全部空间。
是这样理解吗?
谢谢啊,谢谢, 本帖最后由 jackz007 于 2022-9-16 19:43 编辑
howzyao 发表于 2022-9-16 18:52
sub $0x20 , %esp
预留,美元符 %esp栈顶指针的格式。
0x20 就是2000 0000 一个字节的边度十进制数,就 ...
你到底说了些什么乱七八糟的东西?
sub$0x20 , %esp
在 AT&T 汇编中,立即数前面要加 $ 符号,$0x20 就是 0x20,这一句的意思是将栈顶指针 %esp 的值减去 0x20,%esp 指针会因此而向下移动 0x20 字节,这样操作的结果,意味着这 0x20 个字节的堆栈空间已经被占用,那么,%esp ~%esp + 0x1f 一共 32(0x20) 个字节的内存就属于被保护空间,之后,所有的堆栈操作都不会占用到这个空间。
预留的这 32 个字节的空间足够供 8 个整(或浮点)型变量进行使用(4 x 8 = 32)。
立即数前面要加 $ 符号 sub$0x20 , %esp
将栈顶指针 %esp 的值减去 0x20,%esp 指针会因此而向下移动 0x20 字节
我能不能向你从个师?你收不收弟子?
谢谢指导啊. 立即数
以前听到了,以为就是在main中 随手输的 右值,现在才进一步明白.上升到寄存器的微观上,立即数 实际上是 空间长短的数量. 本帖最后由 jackz007 于 2022-9-16 20:13 编辑
howzyao 发表于 2022-9-16 19:51
立即数
以前听到了,以为就是在main中 随手输的 右值,现在才进一步明白.上升到寄存器的微观上,立即数 实际 ...
立即数就是一个 const,就是说,它是一个现成的数,没有那么多其他意思,编译器在编译代码的时候它就已经有了确切的数值,从而被编译器直接写入了汇编指令,就好像为a,b,c 赋初值的指令中所出现的 $0x9 , $0x9, $0x0,这三个数就属于立即数。 本帖最后由 howzyao 于 2022-9-16 21:04 编辑
自己的调式理解:
mov到cmpl之间,处于一段循环:
始 mov %esp,%eax
cmpl %esp 终
esp eax
对于这两个概念,
查了一下:
AX:累积暂存器
EAX、ECX、EDX、EBX:為ax,bx,cx,dx的延伸,各為32位元
EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。
ESP 专门用作堆栈指针,被形象地称为栈顶指针,堆栈的顶部是地址小的区域,压入堆栈的
数据越多,ESP也就越来越小。在32位平台上,ESP每次减少4字节。
esp:寄存器存放当前线程的栈顶指针
ebp:寄存器存放当前线程的栈底指针
以上图的调试源码是这:
for(int i=0;i<le;i++)
b=0.1+(double)i;
页:
[1]