我有这个列表:
list db ' ETA'
和我有一个变量,索引,包含'010'(二进制2)我想索引2个地方到列表使用索引(它代表2)。我有si指向列表,但当我尝试这个:
mov al,[si+index]
它索引到错误的值,因为,我相信,它认为索引表示十六进制数(16)而不是二进制数(2)。我认为这是因为我插入了'2'而不是'索引'和'T',这就是我想要的。这是正在发生的事情吗?我怎样才能避免呢?
让你明白我所说的表现和价值是什么意思:
mov ax,12345 ; load register "ax" with value 12345
现在ax
是什么?一个值。值,通常以十进制格式表示为12345
。但它也是相同的值,可以打印为十六进制格式的0x3039
或二进制格式的0011 0000 0011 1001
。或者可以打印为两个字符长的ASCII字符串,如"90"
(字0x3039
以字节为单位:在小端系统中为0x39 0x30
, 0x39
等于char '9'
, 0x30
等于char '0'
)。当显示为RGB颜色像素时,它将是非常暗的黄色(如果R = 0x39, G = 0x30, B = 0x00)。当作为声音播放时,它可能不会被人类听到(太短而无法形成样本数据)。
这两种ax值的"表现"都不是计算机"看到"它的方式。计算机在16个单元/位(一种电线)中有不同级别的电流,分配为CPU的"ax"。
实际上,对于大多数指令,它甚至不知道我们将特定的单元格(位)与特定的2次幂值(即。1001的二进制是1*23 + 0*22 + 0*21 + 1*20 = 9(十进制)。add ax,bx
指令将从"ax"one_answers"bx"中获取特定单元对,将其(以"add"方式)与临时辅助进位标志混合在一起,并将所得位值放回"ax"单元,从"bit 0"继续到"bit 15",在标志寄存器的进位标志中留下最终进位值。它不需要知道"位3"的值为8,这是稍后在为人类创建输出时生成数字的十进制格式的代码将分配给它的值。
如果index
的值是0b10
,那么索引也包含2
和0x02
,它的值是相同的。在编写代码时如何在源代码中格式化它,或者在计算机屏幕上显示它时如何格式化它-这取决于您,大多数汇编程序支持源中值的广泛可能格式,并且您可以编写代码以任何您希望的方式显示值。
在你的问题[si+index]
看起来像完全不同的问题,你正试图在汇编器中使用"变量",但这不是这些工作方式。index
很可能是内存地址,所以普通汇编程序(NASM)中的mov ax,index
将用内存地址加载"ax",而不是索引中的值。要加载内存的内容,您应该写入mov ax,[index]
。不幸的是,在MASM中,编译器使用伪变量,自动将mov ax,index
转换为mov ax,[index]
,从而混淆了一切。但在[si+index]
的情况下,它将使用地址偏移量,因为没有能够执行[si+[index]]
寻址的指令模式。
所以我猜你正在使用MASM,你对它的"变量"怪癖感到困惑。请阅读英特尔文档,指令参考指南,并了解使用指令可以做什么。
要解决这个问题,首先将index的值加载到某个寄存器中,例如:
mov bx,[index] ; bx = 2
mov al,[si+bx]
BTW,你的问题在调试器中运行时必须是明显的,你应该看到调试器中的指令为mov al,ds:[si+0xSOME_ADDRESS]
而不是mov al,ds:[si+2]
。当某些东西没有按预期工作时,请注意调试器显示的每个细节(并强制它显示所有相关的内容)。指令是否访问内存?如果有你想要的内容,在记忆窗口中偷看一下。堆栈值也一样。当然还有寄存器中的值…