Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 在8086汇编语言中搜索子字符串的程序不工作_Assembly_X86 16_Emu8086 - Fatal编程技术网

Assembly 在8086汇编语言中搜索子字符串的程序不工作

Assembly 在8086汇编语言中搜索子字符串的程序不工作,assembly,x86-16,emu8086,Assembly,X86 16,Emu8086,这是到目前为止我的代码。由于某些原因,我总是在运行时收到“找不到”消息。 我必须检查主字符串(HELLO)中是否存在某个子字符串(HELL)。如何修复代码 .model small COMPARE MACRO LEA DI,SUBSTR MOV CL,LENSUB CLD REPE CMPSB JZ FOUND ENDM .data STR DB "HELLO" LENSTR DB $-STR SUBSTR DB "HELL" LENSUB DB $-SUBSTR MSG1 DB "FOUN

这是到目前为止我的代码。由于某些原因,我总是在运行时收到“找不到”消息。
我必须检查主字符串(HELLO)中是否存在某个子字符串(HELL)。如何修复代码

.model small

COMPARE MACRO
LEA DI,SUBSTR
MOV CL,LENSUB
CLD
REPE CMPSB
JZ FOUND
ENDM

.data
STR DB "HELLO"
LENSTR DB $-STR
SUBSTR DB "HELL"
LENSUB DB $-SUBSTR
MSG1 DB "FOUND$"
MSG2 DB "NOT FOUND$"

.code
MOV AX,@Data
MOV DS,AX
MOV CL,LENSTR
LEA SI,STR
UP:
PUSH SI
PUSH CX
COMPARE
POP CX
POP SI
INC SI
LOOP UP

LEA DX,MSG2
UP1:
MOV AH,09H
INT 21H
JMP LAST

FOUND:
LEA DX,MSG1
JMP UP1

LAST:
MOV AH,4CH
INT 21H
END

您的比较宏代码将永远不会(?)跳转到“查找”,因为您的程序中存在一些错误:

  • 您已经设置了DS段寄存器,但由于
    REPE CMPSB
    指令也使用ES段寄存器,因此您仍然需要设置该寄存器

    MOV AX, @Data
    MOV DS, AX
    MOV ES, AX
    
  • REPE
    前缀期望在CX寄存器中找到重复计数,而您只在CL寄存器中存储一个计数

    LEA DI, SUBSTR
    MOV CL, LENSUB
    MOV CH, 0
    ...
    ...
    ...
    MOV CL, LENSTR
    MOV CH, 0
    LEA SI, STR
    

  • 关于
    循环
    指令
    由于子字符串只能在较大字符串中出现有限的次数,因此不能仅循环较大字符串的总长度。正确的计数为LENSTR-LENSUB+1。这里有5-4+1,2是存储在CX中的正确值

    HELLO
    
    HELL            1st is correct
     ELLO           2nd is correct
      LLO?          3rd is wrong
       LO??         4th is wrong
        O???        5th is wrong
    

    您的比较宏代码将永远不会(?)跳转到“查找”,因为您的程序中存在一些错误:

  • 您已经设置了DS段寄存器,但由于
    REPE CMPSB
    指令也使用ES段寄存器,因此您仍然需要设置该寄存器

    MOV AX, @Data
    MOV DS, AX
    MOV ES, AX
    
  • REPE
    前缀期望在CX寄存器中找到重复计数,而您只在CL寄存器中存储一个计数

    LEA DI, SUBSTR
    MOV CL, LENSUB
    MOV CH, 0
    ...
    ...
    ...
    MOV CL, LENSTR
    MOV CH, 0
    LEA SI, STR
    

  • 关于
    循环
    指令
    由于子字符串只能在较大字符串中出现有限的次数,因此不能仅循环较大字符串的总长度。正确的计数为LENSTR-LENSUB+1。这里有5-4+1,2是存储在CX中的正确值

    HELLO
    
    HELL            1st is correct
     ELLO           2nd is correct
      LLO?          3rd is wrong
       LO??         4th is wrong
        O???        5th is wrong
    


    我敢肯定,像emu8086这样的IDE有一个调试器。你试过了吗?真遗憾。这是非常直观的,虽然-只需点击按钮,以单步和观看节目状态在左边。我们要求您能够自己调试。汇编编程的20%用于编写ASM源代码,80%用于调试(至少在最初的3-5年内,直到您从“新手”到“中级”…再过几年,您可能会达到“稍微高级”的程度,然后您可能最终会编写一些asm代码,这些代码将在第一次尝试时运行(但您仍需对其进行调试以验证这不是意外)…遗憾的是,当该技术过时20年,完全过时10年时,您将在汇编中达到“主”级)。所以,让他们教你的不是1/5,而是4/5。顺便说一句,为什么
    COMPARE
    是一个宏?你甚至不使用它两次,而且它在分析时会中断读取循环,因此更难弄清楚发生了什么。我建议您不惜一切代价避免使用宏(在单次使用的情况下,只需在使用宏的地方编写代码,当可能发生多次使用时,使用相当普通的
    调用过程
    ,宏只能在非常特定的情况下获得性能优势,这不应该困扰您,因为您使用的是低效的过时技术(8086 16b实模式).Hm,也许宏也可以允许用diff regs编写相同的指令链,但请不要。也许你误解了宏的用途?你不会像现在使用它那样从中得到任何好处。我相信IDE(如emu8086)也有一个调试器。你尝试过吗?这很遗憾。它非常直观,但是-只是点击单步按钮,观察左边的程序状态。我们要求您能够自己调试。汇编编程的20%用于编写ASM源代码,80%用于调试(至少在最初的3-5年内,直到您从“新手”到“中级”…再过几年,您可能会达到“稍微高级”,然后您可能最终会编写一些asm代码,这些代码将在第一次尝试时运行(但您仍需对其进行调试以验证这不是意外)…遗憾的是,当该技术过时20年,完全过时10年时,您将在汇编中达到“主”级)。因此,让他们教你的不是1/5的内容,而是4/5的内容。顺便说一句,为什么
    COMPARE
    是一个宏?你甚至不使用它两次,而且它在分析后会打破阅读循环,因此更难弄清楚发生了什么。我建议你不惜一切代价避免使用宏(在单次使用的情况下,只需在使用的地方编写代码,当可能发生多次使用时,使用相当普通的
    调用过程
    ,宏只能在非常特定的情况下具有性能优势,这不应该困扰您,因为您使用的是效率低下的过时技术(8086 16b实模式).Hm,也许宏也可以允许使用diff regs编写相同的指令链,但请不要。也许你误解了宏的用途?你不会像现在使用它那样从中得到任何好处。非常感谢你的回答。我在CL中有计数器,CH默认为00h,所以我认为除非CH在其他地方更改,否则它应该我会很好的。我按照你的建议做了其他更改,现在可以正常工作了。你应该按照建议设置CH=0,这样CX总是处于正确的状态。如果你以后想在其他地方重用你的宏,这一点尤其正确。好的,我会记住。如果你有时间的话,你能看看我的最新帖子吗?我想我面临着数组元素减去的问题。我看到你已经问了下一个问题。如果你发现它对你有帮助的话,请考虑对这个问题进行投票/接受。这就是我们如何确保这个论坛能继续提供帮助的原因。谢谢你的回答。我在CL和CH默认的情况下有计数器,所以我想除非CH在别处被改变。应该没问题。我按照你的建议做了其他更改,现在可以正常工作。你应该按照建议设置CH=0,这样CX总是处于正确的状态。如果你以后想在其他地方重用你的宏,这一点尤其正确。好的,我会记住这一点。可以吗