Assembly 中断21h/09h删除整行而不是打印DX寄存器中存储的字符串
我用的是emu8086。该程序旨在将小写句子转换为大写 int21h/09h的行为很奇怪,它只是删除了整行。我知道它应该输出dx中存储的字符串,但在这里它的行为很奇怪。我不知道为什么在执行这部分代码时会发生这种情况。代码的其余部分工作正常。谁能解释一下吗?如果问题不清楚,请告诉我,我会尽力澄清Assembly 中断21h/09h删除整行而不是打印DX寄存器中存储的字符串,assembly,Assembly,我用的是emu8086。该程序旨在将小写句子转换为大写 int21h/09h的行为很奇怪,它只是删除了整行。我知道它应该输出dx中存储的字符串,但在这里它的行为很奇怪。我不知道为什么在执行这部分代码时会发生这种情况。代码的其余部分工作正常。谁能解释一下吗?如果问题不清楚,请告诉我,我会尽力澄清 mov ah,09h mov dx,offset str int 21h 以下是完整的代码: .model large .data
mov ah,09h
mov dx,offset str
int 21h
以下是完整的代码:
.model large
.data
str db 99,?,99 dup(?)
nl db 10d,13d,'$'
m1 db "Enter a sentence in lowercase: $"
m2 db "Your sentence in uppercase is: $"
.code
;//NEWLINE
newline proc
mov ah,09h
mov dx,offset nl
int 21h
ret
endp
main proc
;//MAIN CODING
mov ax,@data
mov ds,ax
mov es,ax
;//STRING INPUT
mov ah,09h
mov dx,offset m1
int 21h
mov ah,0Ah
mov dx,offset str
int 21h
CALL newline
;//CHARACTER COUNT
mov dx,offset str
mov bx,dx
mov ah,00h
mov al,[bx+1]
mov bp,ax
mov cx,ax
;//CONVERTING LOWERCASE INTO UPPERCASE
mov si,offset str
add si,2
mov bx,0000h
mov ax,0000h
repeat:
mov bl,[si]
mov al,bl
sub al,32d
xchg bl,al
mov [si],bl
inc si
loop repeat
;//PRINTING THE RESULT
mov ah,09h
mov dx,offset m2
int 21h
;//PROBLEM OCCURS HERE
mov ah,09h ;THE PROBLEMATIC LINES
mov dx,offset str ;THE PROBLEMATIC LINES
int 21h ;THE PROBLEMATIC LINES
;//ENDING THE PROGRAM
mov ah,4ch
int 21h
main endp
end main
首先,让我们更改输入变量定义,以简化操作:
str db 99,?,99 dup(?)
将更改为:
str db 99, ?, 99 dup("$")
为什么??DOS中的字符串缓冲区以$结尾,因此我们只需初始化填充有$的缓冲区,这样就不必在代码中添加$
接下来,文本不是从str
地址开始,而是从str+2
Format of DOS input buffer:
Offset Size Description (Table 01344)
00h BYTE maximum characters buffer can hold
01h BYTE (call) number of chars from last input which may be recalled
(ret) number of characters actually read, excluding CR
02h N BYTEs actual characters read, including the final carriage return
因此,第一个字节是缓冲区大小,下一个字节是不需要的,所以字符串实际上以2个字节开始
如果buffer-str
地址从300开始,那么字符串的地址是302,有意义吗
;//PROBLEM OCCURS HERE
mov ah, 09h
mov dx, offset str+2 ; <---- this will print the string
int 21h
//这里出现了问题
mov啊,09h
mov-dx,偏移量str+2 实际上,dup(?)并不意味着用零填充,它意味着它没有初始化,加载程序可以在加载程序时用它想要的任何东西填充它,但是由于我们需要用“$”终止字符串,我们将用它初始化它以使我们的生活更轻松
所以,当我改变这一点时:
str db 99,?,99 dup(?)
为此:
str db 99,?,99 dup("$")
这是:
mov ah,09h
mov dx,offset str
int 21h
为此:
mov ah,09h
mov dx,offset str + 2
int 21h
我们得到了正确的输出
谢谢你,巴德。但这是我第二天设计的。。它还免除了符号和数字的转换:P
.model large
.data
str dw 599,?,599 dup(?)
nl db 10d,13d,'$'
m1 db "Enter a sentence in lowercase: $"
m2 db "Your sentence in UPPERCASE is: $"
.code
;//ALL THE SUB-PROCEDURES
;//NEWLINE
newline proc
mov ah,09h
mov dx,offset nl
int 21h
ret
endp
main proc
;//MAIN CODING
mov ax,@data
mov ds,ax
mov es,ax
;//STRING INPUT
mov ah,09h
mov dx,offset m1
int 21h
mov ah,0Ah
mov dx,offset str
int 21h
CALL newline
;//PRINT PROMPT MESSAGE
mov ah,09h
mov dx,offset m2
int 21h
;//CHARACTER COUNT
mov dx,offset str
mov bx,dx
mov ah,00h
mov al,[bx+1]
mov bp,ax
mov cx,ax
;//CONVERTING LOWERCASE INTO UPPERCASE
mov si,offset str
add si,2
mov bx,0000h
mov ax,0000h
repeat:
mov bl,[si]
mov al,bl
;//IF CHARACTER OTHER THAN LOWERCASE LETTER, PRINT IT AS IT IS
mov bp,0061h ;ASCII 'a'
cmp bx,bp
JL notequal
mov bp,007Ah ;ASCII 'z'
cmp bx,bp
JG notequal
sub al,32d
xchg bl,al
;//PRINTING OUTPUT CHARACTER BY CHARACTER
notequal:
mov ah,02h
mov dl,bl
int 21h
inc si
loop repeat
;//ENDING THE PROGRAM
mov ah,4ch
int 21h
main endp
end main
@ADINBAR lol,谢谢,伙计:)作为一个实验,用lea指令代替通过“偏移量”加载地址。。。如果这有帮助,那么您就知道您有一个源代码问题(我使用的所有汇编程序都有一个副作用,即错误的源代码将导致偏移加载失败,但lea仍然会成功)。另外,如果您有一个合适的调试器,请验证加载的偏移地址(结合段)是否真的指向数据字符串。谢谢,但是我知道所有这些,并且也实现了它dup(?)
实际上意味着数组现在填充了00h
,或者填充了未知值。其次,关于你要求我将2
添加到str
的偏移量,是的,你是对的,我这样做了,原因是第一个字节告诉我们缓冲区的大小,第二个字节告诉我们我们不知道将保存在缓冲区中的字符数,因此是?
。如果你问,我在哪里做的?这是一行代码,它可以做到这一点//将小写转换为大写“”mov-si,offset-str“”add-si,2'为什么在这里使用xchg?原因是我只是简单地扫描每个字节,将它们替换为等效的大写字母sub-al,32d
(32个字符的ASCII差异),然后简单地将原始字节替换为新字节:)注:我已经为从上到下、从下到上以及切换大小写设计了一个更好的编码版本…:P有点花了几个晚上来理解和实施装配:噢。。在执行最终int21h时删除整行的原始问题仍然存在:Pthanks-bud。但这是我第二天设计的。。它还免除了符号和数字的转换:P。。检查我的答案:)嗯,要得到正确的答案,你必须解释问题是什么以及你是如何解决的。发布两大块代码不会为下一个有相同问题的人提供任何价值。