中断21h / 09h删除整行,而不是在DX寄存器中打印存储的字符串

时间:2013-09-08 23:18:33

标签: assembly

我正在使用emu8086。该程序旨在将小写句子转换为大写。

int 21h / 09h 表现得很奇怪,只是删除整行。我知道它应该输出存储在dx中的字符串,但在这里表现得非常奇怪。我不知道为什么在执行该部分代码时会发生这种情况。其余的代码工作正常。有人可以解释一下吗?如果问题不清楚,请告诉我,我会尽力清理它。

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

3 个答案:

答案 0 :(得分:0)

首先,让我们更改输入变量定义以使生活更轻松:

str db 99,?,99 dup(?)

变为:

str      db 99, ?, 99 dup("$") 

为什么呢? DOS中的字符串缓冲区以$终止,因此我们将初始化填充了$的缓冲区,因此我们不必添加$ in代码。

接下来,该文字不会从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个字节!

如果缓冲区 - str地址从300开始,那么字符串的地址是302,有意义吗?

;//PROBLEM OCCURS HERE  
mov     ah, 09h         
mov     dx, offset str+2 ; <---- this will print the string
int     21h             

答案 1 :(得分:0)

实际上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 

我们得到了正确的输出!

enter image description here

答案 2 :(得分:0)

谢谢芽。但这是我第二天设计的......它还免除了符号和被转换的数字: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