【问题标题】:Basic Operational Concepts Assembly基本操作概念组装
【发布时间】:2023-04-09 03:05:01
【问题描述】:

不久前我在 fasm 中学习了一些 x86 汇编。我知道名为 ADD 的指令。例如:

ADD eax,edx ; Precisely ADD destination,source .
The output gets stored in eax.

但今天我读了 Carl Hamacher 的一本关于计算机组织的书,它说:

Add LOCA,R0
"This instruction adds the operand at memory location LOCA to the operand in a register in the processor, R0, and places the sum into register R0."

ADD R1,R0
This instruction adds the contents of register R1 and R0 and places the sum in R0. 

这是什么意思?它违背了我以前学过的任何东西。结果存储在左侧位置。这本书是对的,还是我错了? (第 1.3 页)。

【问题讨论】:

  • 并非所有的汇编语言都是一样的。在某些情况下,源在左侧,目的地在右侧。英特尔语法恰好是目标后跟源。您正在阅读的内容是针对英特尔以外的其他内容(例如,英特尔 x86 没有 r0 和 r1)
  • 那么,您是否建议在某些平台上可以实现 ADD source,destination?谢谢顺便说一句。
  • 添加源、目标和添加目标、源是一回事。由汇编器来创建与指令相关的底层机器代码。 x86 架构有许多汇编程序。大多数使用 Intel 样式,其中目标后跟源(如 NASM、MASM),但 GNU 汇编器(默认情况下)使用 AT&T 语法,源是第一,目标第二。由汇编器将其语法转换为机器代码。由汇编器的开发者来指定语法。
  • 谢谢伙计,我今年 19 岁,对内核和低级的东西充满热情。你的帮助让我的一天变得更好。 +999k 响应
  • 每个 CPU 都有自己的指令集,因此 Intel 的 add 和 ARM 的 add 很可能有些不同(我忽略了明显的区别,比如通用寄存器的不同名称和不同的二进制编码),就像他们可能设置不同的/-ly标志(或者也有根本不使用标志的CPU)等等。但即使在同一个平台上,比如x86,也有不同语法的汇编程序,这将产生完全相同的机器指令,例如 MASM/NASM/FASM/.. 中的 add eax,edx 与 GAS 中的 addl %edx,%eax,但它们的语法即使在参数顺序上也有所不同......

标签: assembly x86 cpu-architecture fasm


【解决方案1】:

首先有许多不同的指令集,x86 只是其中之一,它已经发展了数十年,不断添加指令,更改或重新解释旧指令的工作方式。

其次,汇编语言是由汇编程序定义的,即读取汇编语言的程序。不像 C 或 Python 或 JAVA 或其他有明确的定义,特别是每个人都遵守。汇编语言是并且可以按照汇编程序的作者想要的方式定义。没有关于语言的规则,唯一的规则(如果有的话)是由硬件控制的,要使该工具有用,您需要生成可执行的机器代码。

从历史上看,芯片供应商或在 IP 内核的情况下,内核供应商提供他们自己的文档,其中定义了机器代码和汇编语言,某个地方的某个供应商或代表他们的某人创建了一个汇编器符合该语言的,在 x86 的情况下

add ah,bl

意思是啊=啊+bl

后来有人出现(而且这个工具有这样做的习惯,就是改变汇编语言,使其与芯片/核心供应商工具不兼容)并创建/移植了一个汇编器

add ah,bl

表示 bl = bl + ah

语言差异不仅限于目标优先或最后,包括指令在内的整个语言都是语言的一部分,即使您有 AT&T 语法(目标最后与英特尔语法记住 intel 创建并使这些处理器具有目标优先) 在两个或多个不同的汇编器上,其余语法可能不兼容,正如您应该从 fasm 中知道的那样。

Intel 的原始定义通过重载 mov 助记符而不是隔离寄存器到寄存器、内存到寄存器等,使这变得更加复杂。其他指令集做类似的事情

ldrb r0,[r1]
ldr r0,[r1]

显示这是从某个地址的内存中读取(加载)的 8 位或 32 位。不需要其他语法,但对于 x86,历史上类似

mov [bx], 5

哪条指令不止一个

mov word ptr [bx], 5

好的,但是有些汇编程序你必须使用大写字母而不是小写等等。

因此,就像编程 Python 与 JAVA 一样,您需要了解所编程语言的语法。使用 x86,您可以尝试类似

mov bx,5
mov 5,bx

看看它抱怨或可能需要哪一个

mov %bx,5
mov 5,%bx

要消除其中一个错误,另一个汇编器需要另一种汇编语言。

然后你会进入其他目标,如 arm、mips 等,它们的语法和/或指令将在某些方面与 x86 不同。然后在该目标的各种汇编程序中可能并且将会存在语言差异。出于某种原因,移植 gnu 汇编程序的人倾向于创建与芯片/IP 供应商定义的语言不兼容的语言。它不是一个人做的,只是一个有点一致的主题。

简短的回答,没有被打破,有点预期。语法与工具而非目标相关联。

【讨论】:

  • 我没有任何话要感谢您提供如此丰富的答案。作为一名 CSE 2 年的学生,这样的信息可以帮助我建立强大的基础并保持领先于我的班级和老师。 +无限尊重你的伴侣
  • 另一件事是数字语法,在 C 真正普及之前(在它被发明很多年后)将十六进制数字描述为 $7A 或早期的英特尔语法 7Ah 或者如果它是一个更大的数字并不罕见0C3h 因为 C3h 是标签/字符串而不是数字。一旦 C 语法真正渗透并且我们习惯于键入 0x7A 或 0xC3,汇编程序就开始支持该语法。然后有些人最终放弃了尾随的 h 符号。
  • 当时有些公司是基于八进制的,将指令分解为 3 位字段,有些甚至有 9 位字节和 36 位字。 pdp-11 是一个,尽管你认为它仍然存在。并且维护了一个 gcc 后端和 binutils 端口。该汇编语言与原始的和文档化的语言相比有很大的修改......
  • mov %bx,5 在 AT&T 语法中是 mov [5],bx ...所以它会很高兴地编译(我认为,没有验证)...一个安全的赌注是简单地知道你在使用什么,另一个是检查列表文件/二进制反汇编......
  • 想要一个常量而不是地址,希望常量会失败,因为它不是地址。但我想这取决于汇编程序......
猜你喜欢
  • 2015-05-10
  • 2016-07-06
  • 2021-07-23
  • 1970-01-01
  • 2012-02-19
  • 1970-01-01
  • 1970-01-01
  • 2019-09-26
  • 2013-12-08
相关资源
最近更新 更多