首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我们不能使用esp寄存器直接引用内存地址呢?

为什么我们不能使用esp寄存器直接引用内存地址呢?
EN

Stack Overflow用户
提问于 2019-04-04 21:05:59
回答 2查看 189关注 0票数 0

下面是一个x86组装程序,由NASM在64位CentOS下在远程终端上组装,与C程序一起使用时工作非常好。

代码语言:javascript
复制
section .data
section .text
        global  strlen

strlen:
        push    ebp
        mov     ebp, esp                ; obtain the address of the
        mov     eax, DWORD [ebp+8]      ; address of string to eax

        xor     ecx, ecx                ; initialize counter to zero

count_loop:
        mov     bl, [eax]               ; obtain the address of the 1st character
        cmp     bl, 0                   ; check the null value
        je      length_exit             ; exit if the null-character is reached
        inc     ecx                     ; increment counter
        inc     eax                     ; increment the address
        jmp     count_loop              ; start the loop again

length_exit:
        mov     eax, ecx                ; return ecx
        pop     ebp                     ;
        ret

首先,它是32位还是64位程序?如果它是一个32位程序,为什么它在函数的名称中没有下划线字符(_)?

我知道下面的代码部分正在创建堆栈框架:

代码语言:javascript
复制
push    ebp
mov     ebp, esp                ; obtain the address of the
mov     eax, DWORD [ebp+8]      ; address of string to eax

但是,为什么我们需要拯救ebp呢?为什么我们不能只写以下几句呢?

代码语言:javascript
复制
 move eax, DWORD [esp+8]

我们为什么要在这里做模特儿?

我还需要这个程序的内存布局来理解堆栈机制。我在互联网上发现了很多图片,但我不确定哪一张是代表这个程序的合适图片。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-04 22:04:43

如果它是一个32位程序,为什么它在函数的名称中没有下划线字符(_)?

因为这不是Windows。

Linux/ELF系统在任何模式下都不使用领先的_,而不管其体系结构如何。

为什么我们不能只写以下内容呢?:move eax, DWORD [esp+8]

你可以。(如果拼写正确,则为mov )。事实上,编译器在启用优化时默认使用-fomit-frame-pointer,因此他们只在带有C99可变长度数组或alloca的函数中使用EBP作为框架指针。

32位和64位模式允许ESP成为寻址模式的基本地址,而在16位模式下,[sp+2]是不可编码的。

但是请记住,如果您没有按ebp,ESP仍然指向返回地址,所以第一个arg将位于[esp+4]

我们为什么要在这里做模特儿?

您不需要。寄存器操作数意味着操作数大小.

(这不是真正的类型转换,只是操作数大小的说明符。)它不会对您进行浮点数转换;为此您必须使用cvtss2si eax, [esp+4]。)

您只需要为mem提供一个操作数大小的说明符,即像cmp dword [esp+4], 0这样的即时指令,它在字节/word/dword操作数大小之间是不明确的。或者用于movzx eax, byte [esp+4]这样的指令,其中寄存器操作数并不意味着内存操作数的大小。

票数 1
EN

Stack Overflow用户

发布于 2019-04-04 22:05:12

其原因源于指令的编码方案。

“英特尔手册”第2.1.5节的表2.2显示了可能的组合。

它表明,ESP寄存器的(可能的)编码用于指示SIB字节(指令扩展字节)如下:

--命名意味着SIB遵循ModR/M字节。

因此,从本质上说,ESP寄存器的编码被重用,用于编码额外的指令字节,即SIB字节。

在SIB字节中,[ESP]的指令编码也是一个例外。参见表2.3。

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

https://stackoverflow.com/questions/55524895

复制
相关文章

相似问题

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