gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 10:01:55 26 4
gpt4 key购买 nike

以下是一个 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]

而且,为什么我们需要在此处进行类型转换?

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

最佳答案

If it is a 32-bit program why doesn't it have underscore character (_) in the name of the function?

因为它不是 Windows。

Linux/ELF 系统不使用前导 _在任何模式下,无论 CPU 架构如何。

Why can't we just write the following?: move eax, DWORD [esp+8]

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

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

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

And, why do we need the type-casting here?

你不知道。寄存器操作数表示操作数大小。

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

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

关于linux - 为什么我们不能使用 esp 寄存器直接引用内存地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55524895/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com