了解 8086 汇编器调试器
Understanding 8086 assembler debugger
我正在学习汇编程序,我需要一些帮助来理解调试器中的代码,尤其是标记的部分。
mov ax, a
mov bx, 4
我知道上面的指令是如何工作的,但在调试器中我有“2EA10301”和 "BB0400"。
它们是什么意思?
第一条指令将变量 a 从数据段移动到 ax
寄存器,但在调试器中我有 cs:[0103]
.
这些括号和这些数字是什么意思?
感谢您的帮助。
嗯,首先,汇编程序是 x86 程序集。汇编程序将指令转换为机器代码。
当您反汇编程序时,它可能会使用十六进制值(例如 90 是 NOP 指令或 B8 将某些内容移动到 AX)。
方括号复制寄存器指向的内存地址。
旁边的十六进制称为地址。
2EA10301
和 BB0400
数字是突出显示的两条指令的 opcodes。
2E
是 Code Segment (CS) prefix 并指示 CPU 使用 CS
段而不是默认的 DS
段访问内存。
A1
是 MOV AX, moffs16
的操作码,0301
是 little endian 中的立即数 0103h,即要读取的地址。
所以 2EA10301
是 mov ax, cs:[103h]
.
方括号是表示 memory access through one the addressing mode 的首选方式,但一些汇编器支持不带方括号的令人困惑的语法。
由于这种语法在不同的汇编程序之间是模棱两可的,而且标准化程度低于其他汇编程序,因此不鼓励使用。
在汇编过程中,汇编程序会为发出的每个字节增加一个位置计数器(每个 "section"/段都有自己的计数器,即计数器在每个 "section" 的开头重置)。
这为每个变量提供了一个偏移量,用于访问它和制作指令,变量名是为人类命名的,CPUs 只能从地址、数字中读取。
加载文件后,此偏移量稍后将成为内存中的地址。
汇编器、链接器和加载器协同工作,there are various tricks at play,以确保最终指令在内存中的格式正确,并将偏移量转换为正确的地址。
在您的示例中,他们的努力最终达到值 103h,即内存中 a
的地址。
同样,在您的示例中,如果文件是 COM(顺便说一句,不要在执行流程中放置变量),由于 COM 文件的特殊结构,偏移量仍为 103h。
但总的来说,它可能是另一个数字。
BB
是 MOV r16, imm16
寄存器 BX
。基本形式是 B8
,低 3 位表示要使用的寄存器,BX
表示为值 3(二进制为 011b),实际上是 0B8h + 3 = 0BBh。
在操作码之后,同样是 WORD 立即数 0400
,它在小端编码 4。
您现在可以意识到汇编源代码并不总是包含完整的信息,因为汇编器实现了某种形式的语法糖。
指令 mov ax, a
,其语法与 mov bx, 4
相同,技术上是 移动 立即 值,常量且在汇编时已知,给定通过 a
的地址进入 ax
,被解释为 移动 a
的 content,一个存在于内存中并且只能通过内存访问读取的值,进入 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。
我正在学习汇编程序,我需要一些帮助来理解调试器中的代码,尤其是标记的部分。
mov ax, a
mov bx, 4
我知道上面的指令是如何工作的,但在调试器中我有“2EA10301”和 "BB0400"。
它们是什么意思?
第一条指令将变量 a 从数据段移动到 ax
寄存器,但在调试器中我有 cs:[0103]
.
这些括号和这些数字是什么意思?
感谢您的帮助。
嗯,首先,汇编程序是 x86 程序集。汇编程序将指令转换为机器代码。
当您反汇编程序时,它可能会使用十六进制值(例如 90 是 NOP 指令或 B8 将某些内容移动到 AX)。
方括号复制寄存器指向的内存地址。 旁边的十六进制称为地址。
2EA10301
和 BB0400
数字是突出显示的两条指令的 opcodes。
2E
是 Code Segment (CS) prefix 并指示 CPU 使用 CS
段而不是默认的 DS
段访问内存。
A1
是 MOV AX, moffs16
的操作码,0301
是 little endian 中的立即数 0103h,即要读取的地址。
所以 2EA10301
是 mov ax, cs:[103h]
.
方括号是表示 memory access through one the addressing mode 的首选方式,但一些汇编器支持不带方括号的令人困惑的语法。
由于这种语法在不同的汇编程序之间是模棱两可的,而且标准化程度低于其他汇编程序,因此不鼓励使用。
在汇编过程中,汇编程序会为发出的每个字节增加一个位置计数器(每个 "section"/段都有自己的计数器,即计数器在每个 "section" 的开头重置)。
这为每个变量提供了一个偏移量,用于访问它和制作指令,变量名是为人类命名的,CPUs 只能从地址、数字中读取。
加载文件后,此偏移量稍后将成为内存中的地址。
汇编器、链接器和加载器协同工作,there are various tricks at play,以确保最终指令在内存中的格式正确,并将偏移量转换为正确的地址。
在您的示例中,他们的努力最终达到值 103h,即内存中 a
的地址。
同样,在您的示例中,如果文件是 COM(顺便说一句,不要在执行流程中放置变量),由于 COM 文件的特殊结构,偏移量仍为 103h。
但总的来说,它可能是另一个数字。
BB
是 MOV r16, imm16
寄存器 BX
。基本形式是 B8
,低 3 位表示要使用的寄存器,BX
表示为值 3(二进制为 011b),实际上是 0B8h + 3 = 0BBh。
在操作码之后,同样是 WORD 立即数 0400
,它在小端编码 4。
您现在可以意识到汇编源代码并不总是包含完整的信息,因为汇编器实现了某种形式的语法糖。
指令 mov ax, a
,其语法与 mov bx, 4
相同,技术上是 移动 立即 值,常量且在汇编时已知,给定通过 a
的地址进入 ax
,被解释为 移动 a
的 content,一个存在于内存中并且只能通过内存访问读取的值,进入 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。