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
您的比较宏代码将永远不会(?)跳转到“查找”,因为您的程序中存在一些错误:
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
您的比较宏代码将永远不会(?)跳转到“查找”,因为您的程序中存在一些错误:
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总是处于正确的状态。如果你以后想在其他地方重用你的宏,这一点尤其正确。好的,我会记住这一点。可以吗