我正在尝试以16位实模式编写DOS克隆,虽然一旦我完成了当前的问题,我可能只是学习32位汇编。我的问题在过去一直被否定,但最后一次,我恐怕我确实需要咨询这个网站。改进我之前的问题,我已经做了一些努力,以便在汇编代码中更多地了解指针和堆栈
显然,指令cmpsb
比较了两个字符串,分别位于ES
和DS
。我正在尝试将 INPUT_STRING 的值移至DS
,将 shutmsg 的值移至ES
,这看起来像是正确的寄存器(这些是之前声明的变量)。我的说明似乎没问题,编译得很好,但是当我输入shutdown
时它不起作用,当我通过GDB运行时,它显示的只是
0x0000fff0 in ?? ()
我不知道出了什么问题。我真的没有。这是我的代码:
prompts:
mov si, prompt
call prints
call scans
push ds
mov ds, [INPUT_STRING]
mov es, [shutmsg]
mov cx, 0xFFFF
cld
repe cmpsb
pop ds
je shutdown
mov si, newline
call prints
mov si, INPUT_STRING
call prints
mov si, newline
call prints
jmp prompts
提前致谢,如果再一次这是一个糟糕的问题,我很抱歉。
答案 0 :(得分:4)
实际上cmpsb
分别比较ES:DI
和DS:SI
指向的两个字符串。 ES:DI
我的意思是寄存器对ES
和DI
,其中ES
将保存段地址,DI
将保存偏移地址。 (你明白分段寻址吗?你的问题不清楚。)
查看代码有几件事情不对,例如:
mov ds, [INPUT_STRING]
...会将内存位置INPUT_STRING中的值加载到ds
寄存器中。首先,从你的问题中不清楚INPUT_STRING
是否真的包含指向字符串或字符串本身的指针,但我怀疑(基于你的后续代码)它是字符串本身的位置。因此,您不仅要加载错误的值,而且还只加载ds
而不加载si
。
将正确的值加载到ds
取决于字符串的段地址,并再次在问题中不明显(因此很难为您提供有用的建议)。如果它与代码段相同(可能是针对小型程序),则可以将es
和ds
设置为与cs
相同的值,例如:< / p>
mov ax, cs
mov ds, ax
mov es, ax
(但同样,这只是一个例子。正确的解决方案取决于你的其余代码)。然后,您需要加载si
和di
寄存器:
mov si, INPUT_STRING
mov di, shut_msg
您正在使用cx
加载0xFFFF
:
mov cx, 0xFFFF
为什么呢?字符串恰好是0xFFFF字节长吗?如果不是,你将比不仅仅是字符串的长度而得到一个虚假的结果。
总结: