data segment
S db 20 dup('$')
T db 'true$'
F db 'false$'
A db 'Wabbit$'
ends
stack segment
dw 128 dup(0)
pile:
ends
code segment
start:
mov ax, data
mov ds, ax
mov es, ax
mov dx,offset S
mov ah,10
int 21h
mov cl,S[1]
mov ch,0
mov dx,offset S
add dx,2
mov ah,9
int 21h
mov sp,pile
mov si, 5
mov bp,sp
for1: mov al,A[si]
mov ah,0
push ax
dec si
cmp si,0
jge for1
mov bp,sp
add bp,12
mov si,2
for:
sub bp,2
mov bx,[bp]
mov ax,0
mov al,S[si]
mov ah,0
cmp bx,ax
jne exit
inc si
loop for
mov dx , offset T
mov ah,9
int 21h
jmp endd
exit:
mov dx,offset F
mov ah,9
int 21h
endd:
ends
end start
mov ax, 4c00h ; exit to operating system.
int 21h
ends
end start ; set entry point and stop the assembler.
字符串
这是我的准则
这就是问题所在:
编写一个8086汇编程序,从用户处获取大小为20的字符串S,并确定S的内容是否在给定的单词堆栈(2个字节)的顶部找到,这些单词堆栈已经定义并填充了如下所示的值:
例如:假设S1=“Wabbit”由用户输入,堆栈的内容如上所述,程序将显示“True”,S2=“Exam”,程序将显示“False”。记住堆栈的内容总是固定的“Wabbit”,但是S的内容会改变。
我也有“假”,为什么?
我试着通过一步一步地运行来了解问题,所以当我第一次弹出时,我有74h的“W”的值,但是当我从字符串S中输入“W”的值时,它给出了57h。为什么?为什么?
2条答案
按热度按时间pzfprimi1#
字符串
学会正确使用DOS.BufferedInput函数0Ah。在How buffered input works中阅读所有相关内容。
型
DOS.PrintString函数09 h期望接收一个以$结尾的字符串。您 * 认为 * 通过预加载带有$ characters的缓冲区已经做到了这一点。不能保证一旦函数0Ah返回,这些$字符仍然存在。您应该始终显式地放置$字符。再次,请在How buffered input works中阅读相关内容。
型
mov bp, sp``add bp, 12
行,但最好也删除顶部的mov bp, sp
行,因为这是程序故障的根本原因。您正在比较两个字符串,但对于输入的字符串,从第一个字符开始,对于堆叠的字符串,从最后一个字符开始。* 起点需要对应 *。
而且因为我看不出有什么好的理由首先在堆栈上
push
“Wabbit”字符串,只是像内存中的常规字符串一样遍历它(例如它在 A 处定义),我建议您pop
字符以进行比较:型
loop
指令取决于CX寄存器。别忘了提前初始化它。1.因为您将与已知长度为6个字符的固定字符串进行比较,所以如果输入字符串的长度不是6,则返回'false'是有意义的。
型
您不应该重复这些
ends
和end start
行!fcy6dtqo2#
看你的代码,我可以看到一些逻辑错误。需要理解的最重要的一点是,在使用
push
或pop
时,x86的堆栈必须一次访问两个字节。没有push al
,你必须使用push ax
。您似乎理解这一点,这就是为什么您使用mov ah,0
作为填充。但是,最终用户不能将此填充放入他们键入的字符串中。因此,即使您在程序开始时输入“Wabbit”,您的程序也会尝试将
db "Wabbit"
与db "W",0,"a",0,"b",0,"b",0,"i",0,"t",0
进行比较,这就是为什么您会得到“false”作为答案。为了正确地比较两者,您需要将输入字符串转换为与测试字符串“Wabbit”存储在堆栈上类似的填充形式。(Side注意:我之前给出的例子
db "W",0,"a",0,"b",0,"b",0,"i",0,"t",0
实际上可能是db 0,"W",0,"a",0,"b",0,"b",0,"i",0,"t"
,我不记得当你push ax
时,al
和ah
在堆栈上的顺序是什么。如果一个不起作用,试试另一个。)