JMP对栈指针和帧指针有什么影响?

5

当一个程序集有一个像jmp f的指令时,堆栈和框架指针会发生什么?

我的意思是 - f是内存中的一个标签,对吧?我们如何跳转到内存中的不同地址而不更新我们的框架和堆栈指针...

编辑:我说的是Intel x86汇编语言。

5个回答

7
堆栈指针和帧指针处理数据的位置。jmp指令处理代码的位置。除非发生了某些剧烈的情况,否则它们不应该互相影响。以下是一些剧烈情况的列表:
- 任务切换 - 由于使用任务门进行远跳转 - 故障 - 由于跳转到无效的新页面,或跳出当前段,或jmp试图非法更改特权。 - 陷阱 - 例如,由于代码断点。实际上,我现在想不起来其他的陷阱。
就是这样。即使是这些情况也会改变堆栈,因为它们涉及某种上下文切换,无论是切换到新任务还是切换到某个异常处理程序。
请注意,我所知道的任何操作系统都不使用CPU的任务切换功能。通常是在软件中实现。

1
我认为你的解释让我明白了!JMP是用于跳转到代码中的某个位置,即文本块!我懂了。谢谢! - Andriy Drozdyuk

3

注意:在x86中,有许多种“jmp”指令。最常见的是“本地”jmp,它只是简单地改变EIP寄存器的值,因此栈帧根本不会被触及,正如Carl所指出的那样。我假设你说的是这种类型的jmp,因为这是汇编器用类似于以下语法生成的一种:

jmp label
...

label:

但是还有一个“远跳转”,它也会影响CS段寄存器。如果处理器处于实模式下,那么它仅仅是CS:IP寄存器的变化(只是一个“更大”的跳转),但在保护模式下,CS段具有非常不同且更加复杂的功能:它被解释为CALL/TASK/INTERRUPT门的描述符,即描述符表中的索引,该表定义了许多内容,如特权级别、任务等。根据具体的描述符,可能会发生特权级别升级,或者也可能发生“硬件任务”切换。这可能会产生上下文切换。除非您正在编写操作系统的核心,否则通常不会在保护模式下找到远跳转。创建段描述符几乎总是内核的工作。
此致

3
我猜你在谈论英特尔指令?在这种情况下,任何堆栈/帧指针都不会发生变化,代码只是在相同的上下文中以新地址继续执行。
我猜那个答案有一些警告-使用jmp指令可能会导致任务切换,这时可能会发生各种疯狂的事情。您可能需要阅读所有详细信息的文档。Intel软件开发手册具有所有详细信息:
-jmp 在第2A卷的文档 -第3A卷中的7.3任务切换 编辑:关于您关于跳转而不更新的问题。
您必须能够在不修改堆栈和帧指针的情况下在代码中跳转。例如,在C代码中使用goto-您可以在函数中随意跳跃,而无需修改执行上下文。

请注意,据我所知,没有操作系统实际使用任务处理。 - Nathan Fellman
谢谢,但是Nathan的答案才是我想要的。我猜我不知道自己困惑了什么。 - Andriy Drozdyuk

3

如何在内存中跳转到不同的地址而不更新我们的帧和堆栈指针...

因为指令指针(eip)存储在与帧和堆栈指针(esp、ebp)不同的寄存器中。更改其中一个不会影响其他指针(通常情况下)。


好的,谢谢。我想我会提出更具体的问题,绘制堆栈帧等等,然后再次提问。如果我能在某个地方轻松地绘制它们就好了... - Andriy Drozdyuk

2

JMP是汇编语言中的goto,具有相同的含义。

有时候你需要从不同的地址开始执行程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接