组装emu8086,反向串 [英] Assembly emu8086, reversing a string

查看:125
本文介绍了组装emu8086,反向串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to make a program where the user have to enter a string and get an reversed output. Moreover, it should change all lowercase letters to uppercase and uppercase to lowercase. I've already done program where you can enter 1 character. My next goal is to get as many characters as I want.

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

I did some research and came up with this code:

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.

Now I am getting a wrong output. For example if you enter Hello it will return olleHh. I am completely confused since I can't figure out my error. Also, I am new in Assembly. The output that I expect is 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

推荐答案

您要使其变得复杂.

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

First you display all the letters of your string in reverse order with the following code:

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

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

and then you try to flip the cases with the following code:

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

Problem is with using 0EH service of INT 10H

为什么在输出字符串的末尾会收到多余的h字母?

Why do you get that extra h letter at the end of your output string ?

您正在使用 INT 10h ,该服务用于视频服务和服务

You are using INT 10h which is used for video services and the service 0EH of INT 10h writes the specified character in AL to the current cursor position. Since the last character in AL was capital H in your example and which was flipped to lower case h by your code. That is where you get that extra h at the end of your output string.

为什么不把所有字母都翻过来?

Why don't you get all the letters flipped ?

因为服务 0EH /en.wikipedia.org/wiki/INT_10H"rel =" nofollow noreferrer> INT 10h 只在屏幕上写入一个字符(而不是字符串),而您只得到 H 即可翻转

Since the service 0EH of INT 10h writes only one character to the screen (not the string) you get only H to be flipped.

解决方案:

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

You could have simply flipped the cases and displayed the reverse string in one go and that without using INT 10h.

这是一个简单的代码,该文件已被很好地记录并且可以完成工作:

Here is a simple code which is well documented and that does the job:

 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所说的那样,您应该在程序中使用注释,因为这可以解释您要在程序中执行的操作,并使人们可以轻松地对其进行调试.

And as @Ped7g said you should use comment in your program because that explain what you are trying to do in your program and makes it easy for people to debug it.

这篇关于组装emu8086,反向串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆