我正在学习汇编程序,我需要一些帮助来理解调试器中的代码,尤其是标记的部分。
mov ax, a
mov bx, 4
我知道上面的指令是如何工作的,但在调试器中我有“2EA10301”和“BB0400”。
他们的意思是什么?
第一条指令将变量a从数据段移动到ax
寄存器,但在调试器中我有cs:[0103]
。
这些括号和这些数字是什么意思?
谢谢你的帮助。
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的首选方法,但是一些汇编程序支持不带括号的混淆语法。
由于这种语法在不同的汇编程序中不明确且不太标准化,因此不鼓励使用。
在组装期间,汇编器保持位置计数器针对发出的每个字节递增(每个“部分”/段具有其自己的计数器,即计数器在每个“部分”的开始处重置)。 这为每个变量赋予一个偏移量,用于访问它并制作指令,变量名称用于人类,CPU只能读取地址,数字。
一旦加载文件,此偏移将在以后在内存中寻址。
汇编器,链接器和加载器合作,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
的内容,一个存在于内存中的值并且只能通过内存访问进入ax
,因为已知a
是一个变量。
这种现象在x86中受到限制,即CISC,并且在RISC世界中更为普遍,在pseudo-instructions世界中缺乏常用的指令用qazxswpoi补偿。
好吧,首先,汇编程序是x86汇编。汇编程序将指令转换为机器代码。
当您反汇编程序时,它可能会使用十六进制值(如90是NOP指令或B8将某些东西移动到AX)。
方括号复制寄存器指向的存储器地址。侧面的十六进制称为地址。
一切都很简单。命令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。