相关疑难解决方法(0)

什么是x86"ret"指令相当于?

假设我在x86程序集中编写例程,比如"add",它添加了两个作为参数传递的数字.

在大多数情况下,这是一个非常简单的方法:

push ebp
mov ebp, esp
mov eax, [ebp+8]
add eax, [ebp+12]
mov esp, ebp
pop ebp
ret
Run Code Online (Sandbox Code Playgroud)

但是,有没有什么方法可以重写这个方法来避免使用"ret"指令并仍然产生完全相同的结果?

x86 assembly return

13
推荐指数
4
解决办法
2万
查看次数

在ESP下面写下是否有效?

对于32位Windows应用程序,使用ESP下面的堆栈内存进行临时交换空间而不显式减少ESP是有效的吗?

考虑一个返回浮点值的函数ST(0).如果我们的价值目前在EAX,我们会,例如,

PUSH   EAX
FLD    [ESP]
ADD    ESP,4  // or POP EAX, etc
// return...
Run Code Online (Sandbox Code Playgroud)

或者不修改ESP寄存器,我们可以:

MOV    [ESP-4], EAX
FLD    [ESP-4]
// return...
Run Code Online (Sandbox Code Playgroud)

在这两种情况下都会发生同样的事情,除了在第一种情况下我们注意在使用内存之前递减堆栈指针,然后在之后递增它.在后一种情况下,我们没有.

尽管有任何实际需要在堆栈上持久保存这个值(重入问题,在PUSH返回值和读取值之间的函数调用等),有没有任何根本原因,为什么写入ESP下面的堆栈这样会无效?

windows x86 assembly abi

11
推荐指数
3
解决办法
447
查看次数

Sandybridge微体系结构中的堆栈引擎是什么?

我正在阅读http://www.realworldtech.com/sandy-bridge/,我在理解一些问题时面临一些问题:

专用堆栈指针跟踪器也存在于Sandy Bridge中并重命名堆栈指针,消除了串行依赖性并删除了多个uop.

什么是dedicated stack pointer tracker实际?

对于Sandy Bridge(和P4),英特尔仍然使用术语ROB.但重要的是要理解,在这种情况下,它只引用了飞行中uops的状态数组

事实上它意味着什么?请说清楚.

x86 assembly intel cpu-architecture

9
推荐指数
1
解决办法
979
查看次数

push和pop如何在程序集中工作

我对pop组装中的实际操作感到困惑.是否pop将值PUSHed最后移动到堆栈上(意味着如果我们MOV在最后一个元素之后的值,它不适用PUSH)或者它只是弹出堆栈中最后一个值(因此,应用于两个MOVPUSH),或者它会弹出堆栈指针指向的值吗?请考虑以下代码:

push $4
mov $5, -4(%esp)
add $4, %esp (esp pointing to an unknown value)
pop %ebp
Run Code Online (Sandbox Code Playgroud)

所以在这段代码中,值的值ebp是4,5,还是指向的未知值esp

x86 assembly callstack

8
推荐指数
2
解决办法
3万
查看次数

ESP是否与EAX一样通用?

在x86架构中,可以做什么EAX但不能用ESP?忘了pushpopcall.

x86 assembly cpu-registers

3
推荐指数
1
解决办法
505
查看次数

“PUSH”指令的操作可以使用其他指令执行吗?

目前在我看来,我们拥有像“Push”这样的指令的唯一原因是用一条指令替换多个 MOV 和算术指令。

有没有更原始的指令不能完成的“PUSH”?

“PUSH”只是一个编译成多个机器代码指令的助记符吗?

x86 assembly instruction-set nasm opcode

3
推荐指数
1
解决办法
239
查看次数

x86 代码将输入读入局部变量?

我是 x86 汇编的新手,并且已经阅读了这篇讨论 NASM x86 中的使用的文章scanf。这很有启发性,但是大多数答案都resd在本节中使用了全局变量.bss。相反,我想scanf通过以下 C 程序进入局部变量:

  #include <stdio.h>
  int main(void) {
      int x;
      scanf("%d", &x);
      return x;
  }
 
Run Code Online (Sandbox Code Playgroud)

x86 代码:

  #include <stdio.h>
  int main(void) {
      int x;
      scanf("%d", &x);
      return x;
  }
 
Run Code Online (Sandbox Code Playgroud)

我遵循 CDECL 调用约定,并使用 C 32 位运行时以及 C 32 位标准库进行链接。

; demo.asm

global main
extern scanf

section .data
fmt: db "%d", 0x00

section .text
main:
    ; prologue
    push ebp
    mov ebp, esp

    ; body

        ; allocate int …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly scanf nasm

3
推荐指数
1
解决办法
131
查看次数

为什么在使用 PUSH 或 POP 指令时不鼓励使用 ESP 寄存器?

我正在检查 C 代码,其中我必须计算出特定程序跟踪中使用的寄存器数量。每当遇到推送或弹出命令时,代码都会忽略存储 ESP 寄存器。我还引用了 X86 指令,它那里写着“ESP,堆栈指针,不应该使用”。为什么?

x86 assembly stack-pointer

2
推荐指数
1
解决办法
3407
查看次数

使用“pushf”并弹出到 32 位寄存器是否会破坏堆栈?

我想通过将 CPU 标志压入堆栈来读取它们,然后将它们弹出到寄存器中,如下所示:

uint32_t getEflags() {
    uint32_t eflags;
    asm ("pushf");
    asm ("pop %eax");
    asm ("mov %%eax, %0" : "=r"(eflags));
    return eflags;
}
Run Code Online (Sandbox Code Playgroud)

现在我发现这是一个错误,因为Pushf只压入 EFLAGS 的低 16 位,然后我将它们弹出到 32 位寄存器中(我需要Pushfd)。

这意味着我弹出的内容基本上比最初推送的要多 - 返回这里时我的堆栈会发生什么情况?

c assembly kernel osdev

2
推荐指数
1
解决办法
1175
查看次数

堆栈指针寄存器如何工作

好吧,堆栈是如何工作的?例如说明:

push ax
Run Code Online (Sandbox Code Playgroud)

等于:

sub sp, 4
mov sp, ax
Run Code Online (Sandbox Code Playgroud)

其中sp是堆栈指针.是对的吗?

我的问题是 - 如果片刻后我将其更改为完全不同的值,那么从sp寄存器中减去4是什么意思?

x86 stack-pointer

1
推荐指数
1
解决办法
539
查看次数