首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NASM存储器寻址

NASM存储器寻址
EN

Stack Overflow用户
提问于 2016-12-07 19:17:27
回答 2查看 1.7K关注 0票数 0

我在玩程序命令行参数。特别是,我试图对字符串argv1进行一些测试。如果我使用两步方法将地址获取到argv1,那么我的代码就运行得很好。

代码语言:javascript
复制
mov ebx, [ebp+12]
mov eax, [ebx+4] ; address of argv[1]

如果我用一步的话,我的程序就会打印jibberish。

代码语言:javascript
复制
mov eax, [ebp+16] ; address of argv[1]

假设这两种方法现在都会引用地址ebp+16,这是否是错误的?我是不是错过了一些琐碎的东西?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-12-08 02:02:40

在程序集中使用指向指针的指针时,很容易混淆。

argv是一个“字符串数组”,或者更好的是一个指向char的指针数组,因为在C数组中,当作为参数传递时,它会衰减为指向其项类型的指针,而实际上,argv是指向char或char** argv的指针。

这告诉我们,我们需要两个取消引用来访问任何字符串的字符,另一个需要访问指向任何这样的字符串的指针。

假设参数以反向顺序传递到堆栈上的cdecl约定,并假设设置标准框架指针的标准prolog,则argc的值位于ebp+0ch

请注意,ebp具有指针的语义,因此ebp+0ch只是获取另一个指针的指针算法,这次是指向argc值的指针。

如果我们愿意给ebp+0ch一个C类型,它将是char***,因此需要两个取消引用来访问指针argv[1]

argv[1]进入ESI的代码是:

代码语言:javascript
复制
;typeof(ebp+0ch) = char***

mov esi, DWORD [ebp+0ch]      ;1st defer, esi = argv, typeof(esi) = char**
mov esi, DWORD [esi+04h]      ;2nd defer, esi = argv[1], typeof(esi) = char*

;Optional, Get a char
mov al, BYTE [esi]            ;3rd defer, al = argv[1][0], typeof(al) = char

类型检查。

听起来很混乱?

让我们画出那些指点!

代码语言:javascript
复制
       The stack                                     The memory

100ch | 2000h  | argv                         2000h | 2008h   | argv[0]
1008h | 2      | argc                         2004h | 2010h   | argv[1]
1004h | yyyyyy | return address               2008h | file    | argv[0][0..3]
1000h | xxxxxx | old frame pointer            200ch | .a\0\0  | argv[0][4..7]
                                              2010h | -arg    | argv[1][0..3]
EBP = 1000h                                   2014h | 1\0\0\0 | argv[1][4..7]

ebp+0ch为1000 h+ 0ch =100 0ch,它是argv值的地址。

mov esi, DWORD [ebp+0ch]mov esi, DWORD [100ch]类似,它将ESI设置为2000 H。

2000 H是argv的值,它是一个数组,所以它是argv[0]的地址。

argv[1]的地址在前面四个字节,因此2000h+04h =2004。

mov esi, DWORD [esi+04h]就像mov esi, DWORD [2004h],它将ESI设置为2010 h。

2010 h是字符串"-arg1“的地址。

请注意,上面的图片不符合C或C++标准,因为argv[argc]必须是0。

我把它忘在照片上了。

票数 4
EN

Stack Overflow用户

发布于 2016-12-07 21:29:18

这就是你问题的答案。

代码语言:javascript
复制
mov eax, [ebp+16] 
lea ebx, [ebp+12] 
mov eax, [ebx+4]

代码语言:javascript
复制
mov eax, [ebp+16]
mov ebx, ebp
add ebx, 12
mov eax, [ebx+4]

前者保存了一些字节的代码,但它们在功能上是等价的。

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41025582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档