Assembly 为什么“cmpsb”似乎不比较寄存器的值?

Assembly 为什么“cmpsb”似乎不比较寄存器的值?,assembly,nasm,x86-16,Assembly,Nasm,X86 16,我正在尝试以16位实数模式编写DOS克隆,尽管一旦我完成了当前版本,我可能会学习32位汇编。我的问题在过去一直被否定,但这是最后一次,我担心我确实需要咨询这个网站。在我前面的问题的基础上,我做了更多的努力来学习汇编代码中的指针和堆栈。 显然,指令cmpsb比较了分别位于ES和DS中的两个字符串。我正在尝试将输入字符串的值移动到DS,将shutmsg的值移动到ES,这两个寄存器看起来像是正确的寄存器(这些是之前声明的变量)。我的指令看起来没问题,编译也很好,但当我键入shutdown时,它就不起作

我正在尝试以16位实数模式编写DOS克隆,尽管一旦我完成了当前版本,我可能会学习32位汇编。我的问题在过去一直被否定,但这是最后一次,我担心我确实需要咨询这个网站。在我前面的问题的基础上,我做了更多的努力来学习汇编代码中的指针和堆栈。
显然,指令
cmpsb
比较了分别位于
ES
DS
中的两个字符串。我正在尝试将输入字符串的值移动到
DS
,将shutmsg的值移动到
ES
,这两个寄存器看起来像是正确的寄存器(这些是之前声明的变量)。我的指令看起来没问题,编译也很好,但当我键入
shutdown
时,它就不起作用了,当我通过GDB运行它时,它只显示

0x0000fff0英寸??()

我不知道怎么了。我真的不知道。这是我的密码:

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

如果这又是一个糟糕的问题,请提前感谢,并表示抱歉。

事实上,
cmpsb
分别比较了由
ES:DI
DS:SI
指向的两个字符串。所谓
ES:DI
我指的是一对寄存器
ES
DI
,其中
ES
将保存段地址,
DI
将保存偏移地址。(你理解分段寻址吗?你的问题不清楚)

查看您的代码,有几点不正确,例如:

mov ds, [INPUT_STRING]
。。。将内存位置输入字符串中的值加载到
ds
寄存器中。首先,您的问题不清楚
INPUT\u STRING
是否真的包含指向字符串或字符串本身的指针,但我怀疑(根据后续代码)它是字符串本身的位置。因此,您不仅加载了错误的值,而且只加载了
ds
,而不是
si

将正确的值加载到
ds
取决于字符串的段地址,这在问题中也不明显(因此很难给您提供有用的建议)。如果它与代码段相同(可能适用于小型程序),则可以将
es
ds
设置为与
cs
相同的值,类似于:

mov ax, cs
mov ds, ax
mov es, ax
(但同样,这只是一个示例。正确的解决方案取决于代码的其余部分)。然后需要加载
si
di
寄存器:

mov si, INPUT_STRING
mov di, shut_msg
您正在使用
0xFFFF
加载
cx

mov cx, 0xFFFF
为什么??字符串的长度是否正好为0xFFFF字节?如果不是,您将比较字符串的长度,并得到一个虚假的结果

总之:

  • 您需要了解分段寻址模型,以及分段寄存器的用途
  • 您需要了解字符串值和字符串指针之间的区别,以及值和指针之间的区别
  • 您需要了解字符串是如何存储在内存中的
  • 您需要阅读并理解指令行为/语义

DS和ES是段寄存器,只有指针的一半。指向这两个字符串的完整指针是DS:SI和ES:di。您在哪里读到
cmpsb
比较了“分别位于ES和DS中”的两个字符串?看来你需要继续阅读。@cHao-hmm。。。尝试时,汇编器抛出“操作码和操作数的无效组合”@davmac我想在某个在线文档网站上,但是,再次检查,我看到它是DS:SI和ES:DI@SafalAryal我祝你一切顺利,但是,如果你每次碰到一点小小的障碍就浏览一下内容,跳转到stackoverflow,你就不会走得很远了。你需要做你自己的研究。谢谢!根据我之前提出的一个问题,这两个值都是指向字符串的指针。如果你想(绝对不想,我现在可以解决这个问题)我的完整代码是。另外一个问题(不是我自己的问题)告诉我,由输入函数创建的C风格字符串有那个长度,我现在正在阅读分段寻址模型。我确实需要学习这一点。@SafalAryal从您的代码中我看到,
INPUT\u STRING
是保留字节区域的标签。所以,
mov si,INPUT_STRING
加载
si
,并将指针指向该区域,是的。但是,
mov-si,[INPUT_-STRING]
做了其他的事情——它从内存区域加载一个字大小的值。如果
INPUT\u STRING
是一个变量,那么我们不会说它是一个指针。不过,不同的人对此的表述可能略有不同。@SafalAryal我很乐意提供帮助。然而:有很多代码示例——阅读它们,理解它们。它们将对您帮助更大。@SafalAryal:如果
scans
是您的输入函数,它肯定不会总是创建长度
0xffff
的字符串。如果键入'shutdown',然后以nul终止,那么长度怎么可能是0xffff?如果算上nul终止符,它是8或9。