汇编emu8086,反转一个字符串

时间:2017-12-08 01:30:47

标签: assembly reverse uppercase lowercase emu8086

我正在尝试创建一个程序,用户必须输入一个字符串并获得反向输出。此外,它应该将所有小写字母更改为大写,大写更改为小写。我已经完成了可以输入1个字符的程序。我的下一个目标是获得尽可能多的角色。

我做了一些研究并想出了这段代码:

org 100h
include emu8086.inc
.DATA
  STR1 DB 0DH,0AH, 'Input: $'
  STR2 DB 0DH,0AH, 'Output: $'
  nl db 0dh,0ah,'$' 

.CODE
  START:
    MOV AX, @DATA
    MOV DS, AX
    cmp al, 0x41h
    JGE IsInLowerCaseRange



  Disp:
    LEA DX,STR1
    MOV AH,09H
    INT 21H

    MOV CL,00
    MOV AH,01H

  Read:
    INT 21H

    MOV BL,AL

    PUSH BX
    inc cx
    CMP AL,0DH

    JZ DISPLAY
    JMP READ

  Display:
    LEA DX,STR2
    MOV AH,09H
    INT 21H

    lea dx, nl
    mov ah,09h
    int 21h

  ANS:
    MOV AH,02H
    POP BX
    MOV DL,BL
    INT 21H
    LOOP ANS

  IsInLowerCaseRange:
    cmp al, 0x5Ah
    jle DisplayLowerCaseLetter
    cmp al, 0x61h
    jge IsInUpperCaseRange
    jmp NotALetter


  DisplayLowerCaseLetter:
    add al, 0x20h
    mov ah, 0xEh
    int 10h
    jmp exit


  IsInUpperCaseRange:
    cmp al, 0x7Ah
    jle DisplayUpperCaseLetter
    jmp NotALetter


  DisplayUpperCaseLetter:
    sub al, 0x20h
    mov ah, 0xEh
    int 10h
    jmp exit 


  NotALetter:
    printn
    print "The input character is not a letter."
    exit:
    hlt 

.EXIT
END  START

现在我收到错误的输出。例如,如果您输入Hello,则会返回olleHh。我完全困惑,因为我无法弄清楚我的错误。另外,我是大会的新人。我期望的输出是OLLEh

工作代码:

org 100h
include emu8086.inc


.DATA
   STR1 DB 0DH, 0AH, 'Input: $'
   STR2 DB 0DH, 0AH, 'Output: $'
   Nl DB 0Dh, 0Ah,'$' 


.CODE
START:
    MOV AX, @DATA
    MOV DS, AX


DISP:
    LEA DX,STR1
    MOV AH,09H
    INT 21H
    MOV CL,00
    MOV AH,01H


READ:
    INT 21H
    MOV BL, AL
    PUSH BX
    INC CX
    CMP AL, 0DH
    JZ DISPLAY
    CMP AL, 'A'                 ; < then A  
    JB  NotALetter
    CMP AL, 'Z'                 ; > then Z 
    JA  AGAIN                   ; repeat again
    JMP CONTINUE1


AGAIN:  
    CMP AL, 'a'                 ; < then a
    JB  NotALetter  
    CMP AL, 'z'                 ; > then z 
    JA  NotALetter       


CONTINUE1:
    JMP READ


DISPLAY:
    LEA DX, STR2
    MOV AH, 09h
    INT 21H
    LEA DX, NL
    MOV AH, 09h
    INT 21h
    POP BX                      ; pop enter key


ANS:
    MOV AH, 02h
    POP BX                      ; pop the character 
    CMP BL, 'a'                 ; check if its in upper case
    JB  toLower                 ; if yes then jmp to toLower 
    SUB BL, 32                  ; if not in upper case then convert to upper case
    JMP CONTINUE2


toLower:
    ADD BL, 32                  ; convert to lower case
    ; Probably have to subtract 32 if BL = 20h


CONTINUE2:
    MOV DL, BL
    INT 21H
    LOOP ANS  
    JMP EXIT                    ; if everything is fine jmp to exit                 


NotALetter:        
    printn
    print "The input character is not a letter."    


EXIT:
    hlt 

.EXIT
END  START

1 个答案:

答案 0 :(得分:1)

你让它变得复杂。

首先,使用以下代码以相反的顺序显示字符串的所有字母:

ANS:
MOV AH,02H
POP BX
MOV DL,BL
INT 21H
LOOP ANS

然后您尝试使用以下代码翻转案例:

IsInLowerCaseRange:
   cmp al, 0x5Ah
   jle DisplayLowerCaseLetter
   cmp al, 0x61h
   jge IsInUpperCaseRange
   jmp NotALetter  

DisplayLowerCaseLetter:
    add al, 0x20h
    mov ah, 0xEh
    int 10h
    jmp exit


  IsInUpperCaseRange:
    cmp al, 0x7Ah
    jle DisplayUpperCaseLetter
    jmp NotALetter


  DisplayUpperCaseLetter:
    sub al, 0x20h
    mov ah, 0xEh
    int 10h 

问题是使用INT 10H的 0EH 服务

为什么你在输出字符串的末尾得到额外的h字母?

您正在使用用于视频服务的INT 10h,并且INT 10h的服务0EH将AL中的指定字符写入当前光标位置。由于AL中的最后一个字符在您的示例中是大写 H ,并且您的代码将其翻转为小写 h 。这是您在输出字符串末尾获得额外 h 的地方。

为什么不让所有字母翻转?

由于0EH的服务INT 10h只向屏幕写入一个字符(而不是字符串),因此只能翻转 H

<强>解决方案:

您可以简单地翻转案例并一次显示反向字符串,而不使用INT 10h

这是一个简单的代码,有详细记录并完成工作:

 org 100h
.DATA

  str1 db 10,13, 'Input: $'
  str2 db 10,13, 'Output: $'    
  errMsg db 10,13, 'The input character is not a letter.$'  

.CODE

  START:    

    mov ax, @DATA
    mov ds, ax

    mov dx, offset str1
    mov ah, 09h
    int 21h

    mov cl,00
    mov ah,01h 

    mov bx, '#'   ; store some random character 
                  ; into stack to remeber when to stop
    push bx       ; poping the character while diplaying

  Read: 

    int 21h

    cmp al, 13    ; check if enter key is pressed

    je DISPLAY    ; if yes then display the letters if any

    cmp al, 'A'     ; check if ASCII value of inputted charater is less than ASCII value of capital A  
    jb  NotALetter  ; if yes then print "no a letter"

    cmp al, 'Z'     ; check if ASCII value of inputted charater is not greater than ASCII value of capital Z 
    jna  letterFound  ; if not then continue 

    cmp al, 'a'     ; check if ASCII value of inputted character is less than ASCII value of small a 
    jb  NotALetter  ; if yes then print "no a letter"

    cmp al, 'z'     ; check if ASCII value of inputted character is greater than ASCII value of small z 
    ja  NotALetter  ; if not then continue 

    letterFound:

    mov bl, al

    push bx         ; store the letter in stack

    jmp READ

  Display:

    mov dx,offset str2
    mov ah,09h
    int 21h

  ANS:

    pop bx

    cmp bl, '#'   ; check if no more letter are available in stack
    je exit       

    mov ah, 02h
    cmp bl, 'a'   ; check if the letter is in upper case
    jb  toLower   ; if yes then jmp to toLower 

    sub bl, 32    ; if not in upper case then convert to upper case
    jmp continue

  toLower:

    add bl, 32  ; convert to lower case

  continue:

    mov dl, bl
    int 21h
    jmp ans

  NotALetter: 

    mov ah, 09h
    mov dx, offset errMsg  ; display error message
    int 21h

  exit:

    mov ah, 04ch
    int 21h

END  START

正如@ Ped7g所说,你应该在你的程序中使用注释,因为它解释了你在程序中尝试做什么,并使人们可以轻松地调试它。