如何将每个句子的第一个字母转换为大写,将所有其他字母转换为小写(汇编)?

时间:2015-10-15 15:37:42

标签: assembly x86 tasm dosbox

下面是一个程序,使每个句子的第一个字母大写。但是,我需要修改这个程序,以便让任何其他单词字母小写。此外,可能会有很多句子。到目前为止,我已经注意到程序在我的电脑上运行得不是很好,但这可能不是我程序的错。无论如何,我在确定如何正确修改此程序以满足要求方面遇到了很多麻烦。非常感谢你提前了!

    .model small
    .stack 100h
    .data 

BUFSIZE EQU 4096 ; constant - the size of the buffer
input db 'data.txt',0 ; default input file
output db 'result.txt',0 ; default output file
msg1 db 'Choose data file [data.txt]: $'
msg2 db 10,13,'Choose result file [rezult.txt]: $'
msg3 db 10,13,'Error, the file could not be found, working with default file: data.txt $'
string1 db 11 dup (?) ; the name of input file
string2 db 11 dup (?) ; the name of result file
handle1 dw ? ; file handles
handle2 dw ?
buffer db BUFSIZE dup (' ') ; buffer
.code
       mov ax, @data ; loading data segment
       mov ds,ax 
       sub cx,cx
       mov si, 80h
       mov cl,es:[si] 
       cmp cx, 0 
       mov bx,0      
       je  label1 
       inc si 
       inc si
       dec cx 

read:  mov al,es:[si]
       cmp al,' '     
       je second
       mov string1[bx],al 
       inc si
       inc bx 
       loop read

second:  
       mov string1[bx],0 

       mov bx,0 
       dec cx

looper:    inc si  
           mov al,es:[si]
           mov string2[bx],al
           inc bx
           loop looper

           mov string2[bx],0 
           mov bx,100h 
           push bx 
           jmp open       

label1:    mov ah, 9
           mov dx, offset msg1
           int 21h

named:     mov ah, 1h 
           int 21h 
           cmp al, 13 
           je eof1
           mov string1[bx],al
           inc bx
           jmp named

eof1:      mov string1[bx],00h

open:      mov ah, 3dh
           mov al, 2
           mov dx, offset string1
           int 21h
           mov handle1, ax
           mov ah, 59h
           int 21h
           cmp al, 2 
           je deflt
           jmp cont

 deflt:     mov ah,9
            mov dx,offset msg3
            int 21h
            mov ah, 3dh
            mov al, 2 
            mov dx,offset input
            int 21h
            mov handle1,ax

cont:      pop bx 
           cmp bx,100h
           je creat2 
           mov ah, 9
           mov dx, offset msg2 
           int 21h

           mov bx,0000h  

label2:    mov ah, 1h
           int 21h
           cmp al, 13
           je eof2
           mov string2[bx],al
           inc bx
           jmp label2

eof2:      mov string2[bx],0
           cmp bx, 0
           je creat1
           jmp creat2

creat1:    mov ah, 3ch
           mov cx, 0
           mov dx, offset output
           int 21h
           mov handle2, ax
           mov ah, 3eh
           mov bx, handle2
           int 21h
           mov ah, 3dh
           mov al, 2
           mov dx, offset output
           int 21h
           mov handle2, ax
           jmp read_s

creat2:    mov ah, 3ch
           mov cx, 0
           mov dx, offset string2
           int 21h
           mov handle2, ax
           mov ah, 3eh
           mov bx, handle2
           int 21h
           mov ah, 3dh
           mov al, 2
           mov dx, offset string2
           int 21h
           mov handle2, ax

doin:

read_s:    mov ah, 3fh 
           mov bx, handle1
           mov cx, BUFSIZE 
           mov dx, offset buffer 
           int 21h
           cmp ax, 0 
           je theend
           mov bx,ax

           cmp buffer[0], 'z' 
           ja searching
           cmp buffer[0], 'a'
           jb searching
           sub buffer[0], 32
           dec bx
cc:

edit:      cmp buffer[bx], '?' 
           je higher
           cmp buffer[bx], '!'
           je higher
           cmp buffer[bx], '.'
           je higher
           jmp searching

higher:    cmp buffer[bx+1], 'a' 
           jae lower
           jmp searching

lower:    cmp buffer[bx+1], 'z'
          jbe changing;
          jmp searching      

changing:  sub buffer[bx+1], 32

searching: dec bx ;
           jnz cc 

           mov cx, ax
           mov ah, 40h
           mov bx, handle2
           mov dx, offset buffer
           int 21h
           jmp doin


theend:    mov ah, 3eh  
           int 21h
           mov bx, handle1 
           int 21h

           mov ah, 4ch    
           int 21h
end

1 个答案:

答案 0 :(得分:1)

嗯,在这两种情况下你必须确保角色是一个大写 - 对于字符串中的第一个字符以及跟随'之后的任何字符。 &#39 ;.每个其他char应该是小写的。

首先创建一个函数,将'A' - 'a'(32)添加到char中,如果char在[a..z]范围内,则将其称为toupper.Now复制此函数并更改它以便减去'A'-'a'(32)来自char,如果它落在[A..Z]范围内。

现在只需遍历字符串,加载每个字符。如果它是空终止符,那么你就完成了。如果它是第一个char,则将其大写,然后将save保存为最后一个char,加载另一个字符并再次尝试。如果它不是null并且它不是第一个char,请检查最后一个char是否是空格。如果是,则将char大写,将其保存为last,然后返回以加载下一个char。但是,如果最后一个char不是空格,则将char设置为小写,将其保存为最后一个char,然后返回加载下一个char。

您可以将lastChar变量初始化为0,以确定当前char是否是字符串中的第一个char。 此外,一些注释和一些更有意义的标签名称将使您的代码更容易在以后返回,或更容易为其他人阅读。 ;) 这是一个值得进入的习惯。

这是一个有效的例子。输出为This Is My Message

;==========================================
; nasm toupper.asm -f bin -o toupper.com
;==========================================
[BITS 16] 
[ORG 0x100]      ; DOS .com program, no header, CS=DS
EntryPoint:
    mov     ax, 0x03                ; set text mode 3 - we should already be in this mode, done to clear the screen
    int     0x10

    push    word myMessage
    call    makePrettyCase

    push    word myMessage
    call    printString

    int     0x20                    ; exit back to dos

;void printString(*str)
printString:
    push    bp
    mov     bp, sp
    add     bp, 4
    mov     si, [bp+0]              ; ds:si ---> string
.getChar:
    lodsb
    test    al, 0xff                ; sets the flags as if we did 'and al, 0xff' - if the zero flag is set, there are no bits set in al, i.e it's 0
    jz      .printStringDone
    mov     ah, 0xe
    int     0x10
    jmp     .getChar
.printStringDone:
    pop     bp
    ret     2

; input:
;       AL = char
; outpt:
;       if al if an alpha char, ensures it is in range A-Z
toupper:
    cmp     al, 'a'
    jb      .toupperDone
    cmp     al, 'z'
    ja      .toupperDone
    add     al, 'A' - 'a'       
.toupperDone:
    ret

; input:
;       AL = char
; outpt:
;       if al if an alpha char, ensures it is in range a-z
tolower:
    cmp     al, 'A'
    jb      .tolowerDone
    cmp     al, 'Z'
    ja      .tolowerDone
    sub     al, 'A' - 'a'       
.tolowerDone:
    ret

; void makePrettyCase(char *string)
makePrettyCase:
    push    bp
    mov     bp, sp
    add     bp, 4                           ; add 2 for the bp we just saved, and 2 for the return address. bp now points at out input var, a pointer to the string
    pusha
    mov     si, [bp+0]                      ; point source index to string
    mov     di, si                          ; point dest index to string
    xor     dl, dl                          ; DL = lastChar, holds 0 for the first char in the string
    mov     dh, ' '                         ; DH = spaceChar (' ') - holds the ascii code for a space
.getNextChar:
    lodsb                                   ; ds:[si] --> al, si = si+1
    test    al, 0xff
    jz      .makePrettyCaseDone
.checkIfFirstInString:                      ; if so, capitalize
;   cmp     byte [lastChar], 0
    cmp     dl, 0
    jne     .checkIfLastWasSpace
    jmp     .makeUpper
.checkIfLastWasSpace:                       ; if so, capitalize
    ;cmp        byte [lastChar], spaceChar
    cmp     dl, dh
    jne     .makeLower
.makeUpper:
    call    toupper
    stosb                                   ; al --> es:[di], di = di+1
    mov     dl, al                          ; save this char as our lastChar
    ;mov        byte [lastChar], al
    jmp     .getNextChar
.makeLower:
    call    tolower
    stosb                                   ; al --> es:[di], di = di+1
    mov     dl, al                          ; save this char as our lastChar
    ;mov        byte [lastChar], al
    jmp     .getNextChar
.makePrettyCaseDone:
    popa
    pop     bp
    ret     2                               ; return and remove the 2 bytes of the input var from the stack

;==========================================
[section .data]
myMessage       db      "THIS IS MY MESSAGE",0