3

我很难找到一个开始学习组装的好地方。我在整个互联网上发现了很多相互矛盾的信息,关于什么是汇编,使用哪些汇编器,什么是汇编器,以及英特尔是否为其特定的 CPU 系列发布了一种“核心”汇编语言(我有一个英特尔x86 CPU,这就是我想学习汇编的目的)。

有人可以解释一下上述的麻烦。据我所知,英特尔发布了带有指令集/参考的 CPU 系列(例如 x86),并且各种汇编程序(MASM、FASM、NASM 等)提供了更高级别的人类可读语言,用于制作机器代码指令。

另外,据我所知,当有人说“汇编语言”时,这实际上是指由许多不同的汇编程序提供的许多不同风格的汇编语言之一。 http://en.wikipedia.org/wiki/X86_assembly_language#Examples MASM 样式程序集与 NASM 样式程序集

我正在寻找的是“第一个”汇编程序,没有 MASM、NASM 等提供的变体(例如大型宏库)。所有这些汇编程序一定来自某个地方,这就是我要寻找的。

基本上,我正在寻找第一个 x86 汇编器/汇编语言,在 MASM、NASM 等之前。有人可以为我提供第一个汇编器的链接吗?

顺便说一句,如果我关于组装的整个逻辑是错误的,有人可以澄清一下!

提前致谢,

程序

4

4 回答 4

7

为了迂腐,你用来直接与 CPU 对话的真正语言是机器码。这意味着找出必须用于某些指令的实际字节值。这显然太乏味且容易出错,因此人们改用汇编程序。汇编程序将机器代码的文本表示形式转换为机器代码本身,并处理各种繁琐的细节,例如计算相对地址等。

对于特定的机器代码,可以有许多不同的汇编程序,每个汇编程序都有自己的关于如何编写程序集的想法。对于 x86 处理器来说尤其如此——从广义上讲,有两种风格:英特尔和 AT&T。然后在其中,不同的汇编器可以有不同的宏和指令集等等。

为了说明,这里是从一些 C 代码生成的程序集示例gcc -S -masm=intel

    cmp     eax, ebx
    jl      .L63
    mov     eax, DWORD PTR inbuffd
    mov     DWORD PTR [esp+8], 8192
    mov     DWORD PTR [esp+4], OFFSET FLAT:inbuf
    mov     DWORD PTR [esp], eax
    call    read
    cmp     eax, -1
    mov     ebx, eax
    mov     DWORD PTR inbytes, eax
    je      .L64
    test    eax, eax
    je      .L36
    mov     eax, 1
    xor     edx, edx
    jmp     .L33

这是使用生成的相同代码段gcc -S -masm=att

    cmpl    %ebx, %eax
    jl      .L63
    movl    inbuffd, %eax
    movl    $8192, 8(%esp)
    movl    $inbuf, 4(%esp)
    movl    %eax, (%esp)
    call    read
    cmpl    $-1, %eax
    movl    %eax, %ebx
    movl    %eax, inbytes
    je      .L64
    testl   %eax, %eax
    je      .L36
    movl    $1, %eax
    xorl    %edx, %edx
    jmp     .L33

这两个片段产生相同的机器代码——不同之处仅在于汇编语法。特别注意参数的顺序是如何不同的(英特尔是目标优先,AT&T 是源优先),指令名称的细微差别,%在 AT&T 中指定寄存器的使用等等。

然后是不同的 CPU。CPU具有一定的架构。这意味着它将执行该架构的指令集。对于该架构,将有一个核心指令集,可能还有用于增强功能或特殊应用的额外指令组。x86 就是一个很好的例子——你有浮点指令,MMx,3DNow!和 SSE 1 到 5。该架构的不同 CPU 可能会也可能不会理解额外的指令;通常有一些方法可以询问 CPU 它支持什么。

当您说“x86 程序集”时,人们理解您的意思是“将在 x86 架构的任何 CPU 上运行的程序集”。

更复杂的 CPU - 特别是那些具有内存管理功能的 CPU(包括 x86)不仅仅执行指令。从80286开始,x86 架构有两种主要模式——实模式和保护模式。核心指令集可以在任何一种模式下按原样使用,但内存在每种模式下的工作方式完全不同,以至于尝试编写可以在任何一种模式下工作的真实世界代码是不切实际的。

后来的 CPU 引入了更多模式。386 引入了虚拟 8086 模式又名 v86 模式,以允许保护模式操作系统运行实模式程序,而无需实际将 CPU 切换到实模式。AMD64 处理器以长模式运行 64 位代码。

一个 CPU 可以支持多种架构——安腾架构被认为是一个独立的架构,英特尔发布的所有支持安腾的 CPU 也都支持 x86,并且可以在它们之间切换。

x86 系列可能是汇编语言的一个过于复杂的例子——它的历史可以追溯到 33 多年前。(32 位)应用程序中使用的核心指令的机器代码与 1978 年发布的 8086 相同。经过多次修订,每次都添加了更多指令

如果您想正确学习 x86 汇编,请考虑:

  • 汇编语言编程的艺术,并有一个适用于 DOS、Windows 和 Linux 的版本。Windows 和 Linux 版本使用作者发明的一种称为 High Level Assembly 或 HLA 的语言,它有点像 x86 汇编,但不是真的。这可能是也可能不是你的一杯茶 - 它不是严格意义上的真正组装,但概念都在那里,之后学习编写正确的组装不会有太大的努力。值得称赞的是,它还包含大量与组装相关的材料,例如有关处理器架构、BIOS、视频等的信息。DOS 版本教授直接 MASM(英特尔)组装。

  • 从头开始编程在 Linux 中教授 AT&T 风格的汇编

对于实际的汇编程序(免费的),请在 Windows 或Linux上尝试MASM32 (intel 风格)。as碰巧的是,Linuxas将组装 Intel 或 AT&T 样式的程序集。

如果您对 x86 架构感到 畏惧,并且愿意为其他架构学习汇编,请考虑从较小的.

于 2012-05-06T08:09:17.950 回答
3

除了迈克尔斯莱德的出色回答外,这里还有一些历史信息:

第一个 x86 汇编程序称为“ASM86”。它由英特尔生产,最初运行在他们的 8 位“ISIS”操作系统上。在 DOS 下运行的更高版本已由在线软件历史博物馆 WinWorld 保存。你可以在这里找到它。随附的手册存档包括 Intel 的 1985 年 ASM86 方言参考手册。它支持熟悉的指令,例如 ASSUME、SEGMENT、DB/DW、END 等,以及更高级别的宏。

我能在网上找到的最古老的 x86 汇编语言参考资料是英特尔 1979 年的 MCS-86 宏汇编语言手册。BitSavers在此处保存了一份 PDF 副本。

原始 ASM86 的设计者之一埃里克·艾萨克森 (Eric Isaacson) 继续编写 A86,一种精神继承者。A86 的方言与 ASM86 非常相似,但对 ASSUME 和 SEGMENT 指令等(Eric Isaacson 将它们称为“繁文缛节”)的繁琐内容放宽或消除了。在提供 OP 似乎正在寻找的裸机汇编语言的精神方面,A86 可能比 ASM86 更好。A86 只有 16 位;为了运行它,你需要一个 DOS 仿真器,或者一台运行旧版本 Windows 的机器(我有一台仍然运行 Windows XP 的旧 IBM Thinkpad x23;我一直在它的 DOS 机器上运行 A86,没有任何问题)。

最后,在OS/2 博物馆有一篇关于在 ISIS-2 平台上使用 ASM86 构建原始 IBM PC BIOS 的精彩博客文章。

于 2020-03-27T17:13:40.513 回答
0

我认为没有核心汇编器这样的东西。他们每个人都有自己的方言。此外,您可能需要在选择之前考虑要为哪个操作系统编写代码。

这似乎是一篇很好的文章,可以帮助您选择从哪个开始:http ://webster.cs.ucr.edu/AsmTools/WhichAsm.html

于 2012-05-06T08:11:37.653 回答
0

很难添加到 Michael Slades 的答案中,但我确实有一些评论。

每个处理器供应商或处理器机器代码的创建者都通过使用助记符(该处理器的一种汇编语言)来做到这一点。通常,在原始处理器文档中定义的程序集,无论是午餐时的餐巾纸还是非常正式和漂亮的文档,都是该处理器的“原始”汇编语言。汇编器(这里是松散的术语,因为它们可以有不同的理解,这里用作解析汇编语言并理想地从中生成机器代码的程序)被编写为读取该汇编语言,并带有正确生成代码所需的附加项以及一些指令等使程序员的工作更轻松(宏,等式(定义)等)。

理想情况下,如果您正在创建一个新的处理器,并且您希望首先获得汇编程序所需的任何认可,然后是其他语言(FORTRAN、BASIC、Pascal、C,一直到现在)(始终需要 C,但显然在今天你不需要帕斯卡或基本等)。如果处理器供应商想要销售芯片,它至少需要制造或签约或以某种方式鼓励组装商。关于 8088/8086,Intel 确实有自己的工具,但是它们当时价格昂贵,而且其他工具更受欢迎(microsoft masm、msvc、borland tasm、pascal、tcc、bcc)。如果我没记错的话,有一个很好的免费汇编程序叫做 a86。现在我们将 nasm 作为一个很好的 x86 自由汇编程序的示例。

英特尔 x86 比规则有点例外,在更接近原始语法的英特尔语法和 AT&T 语法之间存在宗教争论。gnu binutils 倾向于不通过更改来尊重处理器供应商(我个人认为使用不尊重这个词),x86 是最糟糕的,因为他们将 AT&T 作为默认设置,但也支持英特尔(部分,也许是全部)他们的工具(其他语言)。例如,汇编器很长一段时间都使用分号';' 标记行尾和后面的任何内容都是注释,因为 ARM 肯定 binutils 认为这是一个新行,一个新指令并使用 @ 作为注释标记。知道是个人组成了后端,有时这些人自己就是芯片供应商,我明白了,不是一个有组织的团体在做这些事情,

与注释符号一样,随着时间的推移,不同处理器的汇编器使用了相似或相同的指令,不是机器代码但例如 ORG 或 .ORG 的附加标记表示地址。由于您有时需要机器代码所在的物理地址来对指令进行编码,因此用户需要以某种方式指示该地址,并且在您编写一个 asm 程序时可能会在单个文件或一个文件中包含包含的单个文件,并且汇编程序的输出是完整的二进制文件而不是不完整的对象,您需要该地址。这就是为什么您在 gnu 汇编器(gas)中看不到 ORG 语句的原因,gnu 汇编器创建的对象使地址特定指令不完整。由于需要地址和需要链接以解析未知标签。

x86 绝对是我推荐你学习的最后一种汇编语言。这更像是一堂有趣的历史课。处理器已经发展了如此之多,并且在每一步都发生了变化,很早就变成了微编码(大多数处理器都不是微编码的,x86 由于其丑陋的汇编/机器语言几乎需要它来竞争)。

拥有 x86 并不是学习 x86 的好理由。您想学习一个指令集,其中您拥有可以窥探处理器的工具。当然,使用调试器您可以单步执行,但是拥有一个您可以操作以输出任何内容、以任何您希望的方式观看任何内容的模拟器,或者甚至更好的是一个您可以一次看到所有内容的逻辑模拟器,将会使您获得以下体验学习汇编语言的痛苦要少得多。更少的痛苦意味着你应该更多地享受它并坚持而不是放弃。尽管与任何语言一样都需要基本的编程技能,但汇编可以让您快速轻松地陷入困境。你也不想让你的电脑或类似的东西崩溃。(再次在这里,如果您觉得需要从 asm 进行系统调用,请使用 pcemu、dosbox、

于 2012-05-06T14:36:43.570 回答