【问题标题】:Can I write assembly without ever using EBX?我可以在不使用 EBX 的情况下编写程序集吗?
【发布时间】:2021-01-08 02:51:06
【问题描述】:

我并不真正了解 EBX 寄存器的用途。我通过搜索 EBX 的用途得到了不同的答案,但最普遍的共识是 EBX 没有像 EAX、ECX 或 EDX 那样的特殊用途。为什么我需要使用 EBX?我已经从简单的教程中删除了 EBX,并且该程序仍然有效。那么使用EBX的原因是什么?如果没有它我也能工作,我为什么要关心它?

【问题讨论】:

  • 在更多类似 RISC 的架构上,没有个寄存器有特殊用途。它们都可以在任何指令中互换使用。这通常是一件好事。
  • BX 的遗留用途是用作指针,BH 和 BL 是 8080 的 H 和 L 寄存器的 8086 替换寄存器。对于 8086,BX、SI 和 DI 默认使用段寄存器DS(数据段),而BP和SP默认使用段寄存器SS(栈段)。

标签: assembly x86 cpu-registers


【解决方案1】:

拥有一个额外的寄存器意味着您可以在寄存器中保留更多内容,而无需存储/重新加载它。这就是 x86-64 添加 R8..R15 的原因,尽管它们几乎都没有任何特殊用途。

你几乎完全倒着看这个。所有通用寄存器都有一些隐含的用途,但这并不是它们存在的原因。 x86 可以设计为没有“字符串”指令,没有 EDI 或 ESI 寄存器,或者没有很多东西,但这样就很难编写高效的代码。

(关于“为什么存在 x86 寄存器”的更基本的答案是 8086 的原始设计,它旨在使从 8080 移植 asm 源代码足够简单,可以机械地完成。https://retrocomputing.stackexchange.com/questions/5121/why-are-first-four-x86-gprs-named-in-such-unintuitive-order - 这就是为什么在 x86 机器代码中,寄存器编号是EAX,ECX,EDX,然后是EBX)


但是,EBX 确实有一些隐含的用途。在现代代码中,尤其是 cpuid 的 4 个输出之一,以及 cmpxchg8b / cmpxchg16b。在历史 x86 中,作为xlatb 的基址寄存器,在 16 位寻址模式中作为少数可用于寻址模式的寄存器之一。

请参阅Why are rbp and rsp called general purpose registers?,其中包括所有 8 个“传统”寄存器和 R11 的隐式使用。

在 i386 Linux 系统调用调用约定中,EAX 保存调用号,EBX 保存第一个 arg,然后是 ECX、EDX 等。但如果 EBX 不存在,调用约定显然会设计不同。

【讨论】:

  • 我会更多地使用 EBX 作为 EAX 参数吗?或者更多是为了别的?我的意思是更多我的意思是我会更频繁或更频繁​​地使用它。
  • @notevention:我不明白你在问什么。与什么相比?大多数情况下,EBX 只是您想要保存/恢复一个时可以使用的调用保留寄存器之一。
  • 当我需要在函数调用中保存一个局部变量时,ebx 是我的首选。
  • 除非你正在写一些琐碎的东西,否则通常所有你的寄存器都应该很忙。
  • @notevention:您仍在使用 EBX 作为 int 0x80 Linux 系统调用的参数,您只是依赖 Linux 将其(以及除 ESP 之外的其他寄存器)初始化为 @987654330 的行为@ 在静态可执行文件中。事实上,当您在终端上运行程序时,fd=0 标准输入文件描述符指的是同一个读写文件 description。 (即 stdin 和 stdout 在终端的读写打开时彼此重复)。如果您从 strace ./my_prog < /dev/null 之类的文件重定向其输入,它将失败。
猜你喜欢
  • 2010-11-04
  • 1970-01-01
  • 2010-09-05
  • 2020-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-26
  • 1970-01-01
相关资源
最近更新 更多