了解 8086 汇编器调试器

Understanding 8086 assembler debugger

我正在学习汇编程序,我需要一些帮助来理解调试器中的代码,尤其是标记的部分。

mov     ax, a
mov     bx, 4

我知道上面的指令是如何工作的,但在调试器中我有“2EA10301”和 "BB0400"。

它们是什么意思?
第一条指令将变量 a 从数据段移动到 ax 寄存器,但在调试器中我有 cs:[0103].

这些括号和这些数字是什么意思?

感谢您的帮助。

嗯,首先,汇编程序是 x86 程序集。汇编程序将指令转换为机器代码。

当您反汇编程序时,它可能会使用十六进制值(例如 90 是 NOP 指令或 B8 将某些内容移动到 AX)。

方括号复制寄存器指向的内存地址。 旁边的十六进制称为地址。

2EA10301BB0400 数字是突出显示的两条指令的 opcodes

2ECode Segment (CS) prefix 并指示 CPU 使用 CS 段而不是默认的 DS 段访问内存。
A1MOV AX, moffs16 的操作码,0301little endian 中的立即数 0103h,即要读取的地址。
所以 2EA10301mov ax, cs:[103h].
方括号是表示 memory access through one the addressing mode 的首选方式,但一些汇编器支持不带方括号的令人困惑的语法。
由于这种语法在不同的汇编程序之间是模棱两可的,而且标准化程度低于其他汇编程序,因此不鼓励使用。

在汇编过程中,汇编程序会为发出的每个字节增加一个位置计数器(每个 "section"/段都有自己的计数器,即计数器在每个 "section" 的开头重置)。
这为每个变量提供了一个偏移量,用于访问它和制作指令,变量名是为人类命名的,CPUs 只能从地址、数字中读取。

加载文件后,此偏移量稍后将成为内存中的地址。
汇编器、链接器和加载器协同工作,there are various tricks at play,以确保最终指令在内存中的格式正确,并将偏移量转换为正确的地址。
在您的示例中,他们的努力最终达到值 103h,即内存中 a 的地址。
同样,在您的示例中,如果文件是 COM(顺便说一句,不要在执行流程中放置变量),由于 COM 文件的特殊结构,偏移量仍为 103h。
但总的来说,它可能是另一个数字。

BBMOV r16, imm16 寄存器 BX。基本形式是 B8,低 3 位表示要使用的寄存器,BX 表示为值 3(二进制为 011b),实际上是 0B8h + 3 = 0BBh。
在操作码之后,同样是 WORD 立即数 0400,它在小端编码 4。


您现在可以意识到汇编源代码并不总是包含完整的信息,因为汇编器实现了某种形式的语法糖。
指令 mov ax, a,其语法与 mov bx, 4 相同,技术上是 移动 立即 值,常量且在汇编时已知,给定通过 a 的地址进入 ax,被解释为 移动 acontent,一个存在于内存中并且只能通过内存访问读取的值,进入 ax 因为 a 已知是一个变量。

这种现象仅限于x86,CISC, and more widespread in the RISC world, where the lack of commonly needed instructions is compensated with pseudo-instructions

一切都很简单。命令mov ax,cx:[0103]表示将000Ah的值加载到寄存器ax中。该值取自 0103h 处的代码段。在图片中您可以看到这个值略高。 cx: 0101 0B900A00。因此,地址 0101h 的值为 0Bh,0102h 的值为 90h,0103h 的值为 0Ah,0104h 的值为 00h。事实证明,AL 寄存器从地址 0103h 加载值等于 0Ah。事实证明,AH 寄存器从地址 0104h 加载等于 00h 的值,结果 ax = 000Ah。如果不是 ax 命令,cx:[0103],而是 ax 命令,cx:[0101],那么 ax = 900Bh 或者 ax 命令,cx:[0102],那么 ax = 0A90h。