-1

below is a program that makes the first letter of each sentence uppercase. However, I need to modify this program in order for it to make any other word letters lowercase. Also, there could be a lot of sentences. So far, I've noticed that the program doesn't run very well on my PC, but that's probably not the fault of my program. Anyways, I am having a lot of trouble figuring out how to modify this program properly in order to fit the requirements. Thank you a lot in advance!

    .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
Pa2k3l1s
  • 1
  • 6

1 Answers1

1

Well, there's two cases in which you must ensure the character is a capital - for the first char in the string and for any char that follows a ' '. Every other char should be a lower case one.

Start by making a function to add 'A' - 'a'(32) to a char if the char is in the range [a..z], call it toupper.Now duplicate this function and change it so that it subtracts 'A'-'a'(32) from a char if it falls in the range [A..Z].

Now just walk through the string, loading each character. If it's the null terminator, you're done. If it's the first char, capitalize it and then save is as the last char, load another character and try again. If it's not null and its not the first char, check to see if the last char was a space. If it was, capitalize the char, save it as the last and then return to load the next char. If however, the last char wasn't a space, make the char lower-case, save it as the last char and then return to load the next.

You can initialize the lastChar variable to 0 to determine if the current char is the first one in the string. Also a few comments and some more meaningful label names would make your code easier to come back to at a later date, or easier to read for anyone else. ;) Its a habit worth getting into.

Here's a worked example. The output is 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
enhzflep
  • 12,927
  • 2
  • 32
  • 51