免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: sherf
打印 上一主题 下一主题

请教一下大家对桢指针的理解 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-05-22 23:52 |只看该作者
找本汇编教程,把函数那章好好看看吧。BTW,虎书的意思是,你要是懂,看了就懂,你要是不懂,看了也不一定懂,建议有基础了再看吧。

论坛徽章:
0
12 [报告]
发表于 2009-05-23 00:01 |只看该作者

回复 #10 prolj 的帖子

prolj,

谢谢你的建议,也希望你能回答我帖子中提到的问题.......

论坛徽章:
0
13 [报告]
发表于 2009-05-23 00:07 |只看该作者
frame pointer,mik说清楚了。

论坛徽章:
0
14 [报告]
发表于 2009-05-23 00:20 |只看该作者
sherf :


我已经说得很清楚了:

ebp 就是 stack base frame pointer

论坛徽章:
0
15 [报告]
发表于 2009-05-23 00:52 |只看该作者

回复 #13 mik 的帖子

mik,

谢谢,明白了。

是我之前搞错了。如果caller()对应第一桢、callee()对应第二桢的话,那么被调用函数(callee())的参数是应该从第一桢(caller())中获取的。因此,FP指向”上一桢的”,但不是指向“上一桢栈顶”,而是指向 “上一桢栈顶”-4 ,因为之前作了 push ebp 。

而之前,你的例子:
mov eax, [ebp+8] // 参数1
应理解为:
由于 ebp->FP,所以 要找到参数1 的话,需要“第二桢的FP”跨越到第一桢里去取,之所以要偏移8,是因为栈中在第一个参数之前,还有 ebp(处于第二桢), eip(处于第一桢)。

mik,谢谢你的帮助,谢谢

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
16 [报告]
发表于 2009-05-23 10:45 |只看该作者
这个.......还是建议先对机器有一定了解再说,可以看本说汇编的书,里面会介绍的.

论坛徽章:
0
17 [报告]
发表于 2009-05-23 15:30 |只看该作者
看来不同的人有不同的学习方法.
楼上各位大拿的思考侧重点都有些不同.

论坛徽章:
0
18 [报告]
发表于 2009-06-15 17:23 |只看该作者

回复 #15 sherf 的帖子

mik,

目前在看其他相关的程序是发现,有些东西跟这个问题是有关的,想再请教一下你。

mov eax, [ebp+8] // 参数1

我之前的理解是:
由于 ebp->FP,所以 要找到参数1 的话,需要“第二桢的FP”跨越到第一桢里去取,之所以要偏移8,是因为栈中在第一个参数之前,还有 ebp(处于第二桢), eip(处于第一桢)。

现在的疑惑:
[ebp+4] ?= eip

我重新再看程序时,发现尽管里面用到32位寄存器,但是里面并不是处于32位保护模式当中,还是16位实模式,感觉 "word [ebp+4] = cs", "word [ebp+6] = ip"。由于是在linux的nasm下做的程序,而并不是在windows的masm做的程序,因此没法用debug看。

我想再问一下,在这个例子里面,我后面的理解对吗?也就是是不是所有的汇编程序结合c的程序时,c程序调用汇编程序里面的函数(call指令)时都是长转移?(要压CS的)
blackoil 该用户已被删除
19 [报告]
发表于 2009-06-15 22:00 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
20 [报告]
发表于 2009-06-16 11:53 |只看该作者
原帖由 blackoil 于 2009-6-15 22:00 发表
16位模式用32位寄存器,用0x66前缀
32位模式用16位寄存器,同样用0x66前缀

16位模式存取32位地址,[eax+ebx*4]之类的,用0x67前缀
32位模式存取16位地址,之类的,同样也用0x67前缀

一般函数运行时要划 ...



楼上,我还是没有明白你的意思。

其实我的疑惑是在 word[ebp+4] 和 word[epb+6] 这2个地方。原先我是没太留意,以为这里是 eip(4位),但后来就有疑惑了。为什么程序默认是短转移(没有CS的)?举个例子,例如如下程序:

== 汇编 test.asm =======================
extern abc      ; int abc(int a, int b)

[section .data]
param1 dd 1
param2 dd 2

[section .text]
global _start
global printaa

_start:
   push param2
   push param1
   call abc
   add esp, 4
   
   mov ebx, 0
   mov ebx, 1  ; sys_exit
   int 0x80      ; 系统调用

printaa:
   mov edx, [esp + 8]   ; len
   mov ecx, [esp + 4]   ; msg

   
   mov ebx, 1
   mov eax, 4   ; sys_write
   int 0x80       ; 系统调用
   ret
   

== C 程序: ltt.c ================
void printaa( char *msg, int len);

int  abc (int a, int b)
{
    if (a>b)
        printaa("a");
    else
        printaa("b");
}

对于 test.asm :
1、 _start 后面的红色语句 “add esp, 4” ,指向函数abc的第一个参数
2、printaa中蓝色部分“mov ecx, [esp + 4]”,指向函数printaa 中的第一个参数

那对于1和2, dword [esp + 0] 里面都有些什么?(是 eip 还是 “cs 和 ip ”)?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP