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

问题描述 投票:0回答:2

以下是x86汇编程序,旨在由NASM在64位CentOS上通过远程终端进行组装,当与C程序一起使用时,该程序可以正常工作。

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位程序,为什么它在函数名称中没有下划线字符(_)?

我知道以下代码部分正在创建一个堆栈框架:

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

但是,为什么我们需要保存ebp?为什么我们不能写下面的内容? :

 move eax, DWORD [esp+8]

而且,为什么我们需要这里的类型铸造?

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

linux assembly x86 nasm
2个回答
1
投票

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

因为它不是Windows。

无论CPU架构如何,Linux / ELF系统都不会在任何模式下使用领先的_

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

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

32位和64位模式允许ESP作为寻址模式的基地址,这与[sp+2]无法编码的16位模式不同。

但请记住,如果你没有推动ebp,ESP仍然指向返回地址,所以第一个arg将在[esp+4]

而且,为什么我们需要这里的类型铸造?

你没有。寄存器操作数表示操作数大小。

(它不是真正的类型转换,只是操作数大小说明符。它不会为你做float-int转换;你必须使用cvtss2si eax, [esp+4]。)

你只需要mem的操作数大小说明符,像cmp dword [esp+4], 0这样的立即指令,它们在字节/字/双字操作数大小之间是不明确的。或者像movzx eax, byte [esp+4]这样的指令,其中寄存器操作数并不意味着内存操作数的大小。


0
投票

原因源于指令的编码方案。 “英特尔手册”第2.1.5节中的表2.2显示了可能的组合。

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

[ - ] [ - ]命名法表示SIB遵循ModR / M字节。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.