Assembly 如何检查scasb的结果

Assembly 如何检查scasb的结果,assembly,x86,Assembly,X86,我必须在字符串中找到子字符串的(起始)位置。我在AL中逐字节加载字符串,并使用SCASB进行比较。如何检查字节是否相等或SCASB是否为真 clc scasb ;compare the value from al with <es:di> ;al is loaded from <ds:si>(lodsb) ;I noticed that when the values are equa

我必须在字符串中找到子字符串的(起始)位置。我在
AL
中逐字节加载字符串,并使用
SCASB
进行比较。如何检查字节是否相等或
SCASB
是否为真

        clc
        scasb ;compare the value from al with <es:di>
              ;al is loaded from <ds:si>(lodsb)
              ;I noticed that when the values are equal
              ;cf and af are 1
        jnc nextElem ;if cf is 0 go to the next element

        lahf
        cmp  ah,0
        je nextElem ;if af is 0 go to next elem
clc
scasb;将al的值与
;al从(lodsb)加载
;我注意到当值相等时
;cf和af为1
jnc-nextElem;如果cf为0,则转到下一个元素
拉夫
啊,0
je NEXTLEM;如果af为0,则转到下一个元素

问题是,
LAHF
没有带来我在ah中所期望的值,意思不是0或1,我不知道任何其他方法来检查
AL
和中的值是否相等。

Scasb
cmpsb
仅在字符串上使用时有用,长度/计数器在CX寄存器中。以下是在8086 asm中实现的strstr


其思想是使用带有repne前缀的
scasb
(在不相等的情况下重复)来查找字符串中子字符串的第一个字符。如果找到,则使用
repe cmpsb

Scasb
比较字符串的其余部分,
cmpsb
仅在字符串上使用时有用,长度/计数器在CX寄存器中。以下是在8086 asm中实现的strstr


其思想是使用带有repne前缀的
scasb
(在不相等的情况下重复)来查找字符串中子字符串的第一个字符。如果找到,则使用
repe cmpsb

比较字符串的其余部分。我稍微更改了代码,如下所示:

mov  cx,length  ; length of the substring
repe cmpsb      ; compare <ds:si> with <es:di> 
jcxz Pozitie    ; if cx is zero than we found the substring in the string
mov-cx,长度;子串的长度
重复cmpsb;与…比较
jcxz-Pozitie;如果cx为零,则在字符串中找到子字符串

我对代码做了一些更改,就是这样:

mov  cx,length  ; length of the substring
repe cmpsb      ; compare <ds:si> with <es:di> 
jcxz Pozitie    ; if cx is zero than we found the substring in the string
mov-cx,长度;子串的长度
重复cmpsb;与…比较
jcxz-Pozitie;如果cx为零,则在字符串中找到子字符串

如果不想使用跳转指令,而使用“RepNE ScaSB”字符串指令,要查找上一个不匹配字符(CX)的偏移量,可以编写:

 ClD             {Clear string direction flag}

 XOr   AL,AL     {Set AL's reg. with the character to find (0)}
 Mov   CX,0FFFFH {Set CX's reg. with maximum length of the string}

 RepNE ScaSB     {Search null and decrease CX's reg.}

 LAHF            {Load FZero flag into AH (Bit6)}
 Not   CX        {Set CX with the number of char scanned}
 ShL   AH,1      {...}
 ShL   AH,1      {... FCarry is set with (FZero after scan)}
 SbB   CX,0      {If it founds 0 decrease CX's reg.}
如果CX=65535,则未找到该字符


如果不想使用跳转指令,而使用“RepNE ScaSB”字符串指令,要查找前一个不匹配字符(CX)的偏移量,可以编写:

 ClD             {Clear string direction flag}

 XOr   AL,AL     {Set AL's reg. with the character to find (0)}
 Mov   CX,0FFFFH {Set CX's reg. with maximum length of the string}

 RepNE ScaSB     {Search null and decrease CX's reg.}

 LAHF            {Load FZero flag into AH (Bit6)}
 Not   CX        {Set CX with the number of char scanned}
 ShL   AH,1      {...}
 ShL   AH,1      {... FCarry is set with (FZero after scan)}
 SbB   CX,0      {If it founds 0 decrease CX's reg.}
如果CX=65535,则未找到该字符



提到更多细节。
scasb
指令文档的第一句话:“scasb将AL中的字节与[ES:DI]或[ES:EDI]处的字节进行比较,并相应地设置标志。”如果要检查是否相等,请使用ZF。CF用于测试是否小于。@Tirstrajbarot我在问题中添加了一些代码。我希望你明白我的意思。@RaymondChen我试过了,但zf没有改变,所以即使值不同,它也会继续。你为什么要首先使用LAHF?既然在EFLAGS中已经有了所需的标志,为什么不在条件上进行分支呢?请提及更多细节。
scasb
指令文档的第一句话:“scasb将AL中的字节与[ES:DI]或[ES:EDI]处的字节进行比较,并相应地设置标志。”如果要检查是否相等,请使用ZF。CF用于测试是否小于。@Tirstrajbarot我在问题中添加了一些代码。我希望你明白我的意思。@RaymondChen我试过了,但zf没有改变,所以即使值不同,它也会继续。你为什么要首先使用LAHF?既然你已经在EFLAGS中有了你想要的标志,为什么不在一个条件上进行分支呢?你最好给出一个实际的例子,而不是提供这个链接!作者明确地问:“请不要撕开!做:链接”,它在页面的顶部:)我不同意
scasb
。。。仅在
CX
寄存器中长度为的字符串上使用时才有用
scasb
和朋友们在没有使用
CX
寄存器的情况下完美地运行了。如果作者不允许复制,那就创造一个你自己的例子。你最好展示一个实际的例子,而不是提供这个链接!作者明确地问:“请不要撕开!做:链接”,它在页面的顶部:)我不同意
scasb
。。。仅在
CX
寄存器中长度为的字符串上使用时才有用
scasb
和朋友们在没有使用
CX
寄存器的情况下完美地运行了。如果作者不允许复制,那么就自己创建一个例子。REPE CMPSB也会设置标志,而JCC on标志通常比JCXZ更有效(例如,我还没有对此进行测试,但是这里,
JNE Pozitie
应该是JCXZ的确切替代品,只有在
repe cmpsb
提前停止的情况下才是如此。repe cmpsb也保留设置的标志,JCC on标志通常比JCXZ更有效。)(例如,我还没有对此进行测试,但是
JNE Pozitie
应该是JCXZ的精确替代品,只有在
repe cmpsb
提前停止时才是如此。
shl-ah,2
会更有效(英特尔P6系列除外,在该系列中,使用imm8移位的标志结果将暂停)。这不是8086唯一的问题(虽然它似乎是16位的)。另外,你能不能停止在答案的底部加上“嗨!”?堆栈溢出不允许签名行。你能
setz al
setnz al
/
sub-ax、cx
或其他什么吗?(如果你在scasb之前将整个ax/EAX归零,而不仅仅是al)。可能还需要另一个+或-1或其他东西来解释NEG与非2的补码。
shl ah,2
将更有效(英特尔P6系列除外,在该系列中,使用imm8移位的标志结果将暂停)。这不是唯一的8086问题(尽管它似乎是16位)。此外,您能否停止输入“Hi!”在你答案的底部?堆栈溢出不允许签名行。你可以吗