Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

convert characters

theozistheozis Member Posts: 4
[b][red]This message was edited by theozis at 2003-2-14 0:4:31[/red][/b][hr]
halo,do everybody have the full sourcecode for this program, convert characters from lower case to upper case.
it using 8X86 microprocessor and can do like this:
example:
1)read from a file which have sentence like this:
I am a student
2) edit this file to this:
I AM A STUDENT
3)then , save the file and exit

since i'm a newbird, i hope that all of you can help me in this case..thank a lot to all of you..


Comments

  • asmosprogasmosprog Member Posts: 54
    : [b][red]This message was edited by theozis at 2003-2-14 0:4:31[/red][/b][hr]
    : halo,do everybody have the full sourcecode for this program, convert characters from lower case to upper case.
    : it using 8X86 microprocessor and can do like this:
    : example:
    : 1)read from a file which have sentence like this:
    : I am a student
    : 2) edit this file to this:
    : I AM A STUDENT
    : 3)then , save the file and exit
    :
    : since i'm a newbird, i hope that all of you can help me in this case..thank a lot to all of you..
    :


    To convert a lower case to upper case you can use the following code. The character is located at DS:SI.


    ConvertCharacter:

    push ax
    mov al,[si]
    cmp al,'a'
    jb .DoneConvert
    cmp al,'z'
    ja .DoneConvert
    sub al,020h
    mov [si],al

    .DoneConvert:

    pop ax
    retn


    You can then set up a loop to call this function for every character. SI is not incremented in this function so you will need to do it elsewhere.


    To open a file, you use function 03Dh of interrupt 021h. To read a file, AX needs to be set to 03D00h and for writing it needs to be 03D01h. 03D01h will work only if the file already exists so it is better to use AH = 03Ch to create the file if it does not exist. DS:DX is where the ASCIIZ (zero-terminated ASCII string) file name is. If the carry flag is set on return of either function then AX will contain an error code (and the file was not opened). Here is an example.


    FileToOpen db '.MYFILE.TXT',0
    OutputFile db '.MYFILEU.TXT',0
    ReadFileHandle dw 0
    WriteFileHandle dw 0


    OpenForRead:

    mov ax,03D00h
    int 021h
    jc .Return
    mov [ReadFileHandle],ax

    .Return:

    retn


    OpenForWrite:

    mov ah,03Ch
    xor cl,cl
    int 021h
    jc .Return
    mov [WriteFileHandle],ax

    .Return:

    retn


    A file handle is required to be able to access a file in DOS. It tells DOS what file to access. This needs to be saved for later use. After you are done with a file it is best to close it. Using AH = 04Ch to exit the program will close all files but this is bad programming practice. The file handle needs to be sent to function 03Eh so it knows which file to close. If the carry flag is set when this function returns then there was an error closing the file. If so, you should recall the function. BX needs to already contain the file handle. Here is some code.


    CloseFile:

    mov ah,03Eh
    retn


    To read and write to files, you just need to call functions 03Fh and 040h of interrupt 021h. BX contains the file handle an CX the number of bytes to read/write from the file. DS:DX points to the location in memory to read/write the data to/from. On return, AX will contain the amount of bytes that actually were read/written. For reading if this was less than you requested then the end of file was found. Once again, if CF is set then there was an error.


    ReadFromFile:

    mov ah,03Fh
    mov bx,[ReadFileHandle]
    int 021h
    retn


    WriteToFile:

    mov ah,040h
    mov bx,[WriteFileHandle]
    int 021h
    retn


    Here is what you could use for a main loop. I have tested this code and it works fine.


    MainCode:

    mov ax,cs
    ;mov ds,ax
    mov dx,FileToOpen
    call OpenForRead
    jc .OpenReadError
    mov dx,OutputFile
    call OpenForWrite
    jc .OpenWriteError

    .ReadConvertWrite:

    mov dx,Buffer
    mov cx,16
    call ReadFromFile
    jc .ErrorReading
    mov si,Buffer
    mov cx,ax
    jcxz .Done

    .ConvertByte:

    call ConvertCharacter
    inc si
    loop .ConvertByte

    mov cx,ax
    mov dx,Buffer
    call WriteToFile
    jc .ErrorWriting
    test ax,ax
    jnz .ReadConvertWrite

    .Done:

    mov bx,[ReadFileHandle]
    call CloseFile
    mov bx,[WriteFileHandle]
    call CloseFile
    mov ax,04C00h
    int 021h

    .OpenReadError:

    mov ah,9
    mov dx,OpenReadError
    int 021h
    jmp .Done

    .OpenWriteError:

    mov ah,9
    mov dx,OpenWriteError
    int 021h
    jmp .Done

    .ErrorReading:

    mov ah,9
    mov dx,ReadError
    int 021h
    jmp .Done

    .ErrorWriting:

    mov ah,9
    mov cx,WriteError
    int 021h
    jmp .Done


    Buffer dw 0,0,0,0,0,0,0,0
    OpenReadError db 'Error opening input!',10,13,'$'
    OpenWriteError db 'Error opening output!',10,13,'$'
    ReadError db 'Error reading input!',10,13,'$'
    WriteError db 'Error writing output!',10,13,'$'


    Michael Gallagher
    asmosprog@hotmail.com
  • theozistheozis Member Posts: 4
    : : [b][red]This message was edited by theozis at 2003-2-14 0:4:31[/red][/b][hr]
    : : halo,do everybody have the full sourcecode for this program, convert characters from lower case to upper case.
    : : it using 8X86 microprocessor and can do like this:
    : : example:
    : : 1)read from a file which have sentence like this:
    : : I am a student
    : : 2) edit this file to this:
    : : I AM A STUDENT
    : : 3)then , save the file and exit
    : :
    : : since i'm a newbird, i hope that all of you can help me in this case..thank a lot to all of you..
    : :
    :
    :
    : To convert a lower case to upper case you can use the following code. The character is located at DS:SI.
    :
    :
    : ConvertCharacter:
    :
    : push ax
    : mov al,[si]
    : cmp al,'a'
    : jb .DoneConvert
    : cmp al,'z'
    : ja .DoneConvert
    : sub al,020h
    : mov [si],al
    :
    : .DoneConvert:
    :
    : pop ax
    : retn
    :
    :
    : You can then set up a loop to call this function for every character. SI is not incremented in this function so you will need to do it elsewhere.
    :
    :
    : To open a file, you use function 03Dh of interrupt 021h. To read a file, AX needs to be set to 03D00h and for writing it needs to be 03D01h. 03D01h will work only if the file already exists so it is better to use AH = 03Ch to create the file if it does not exist. DS:DX is where the ASCIIZ (zero-terminated ASCII string) file name is. If the carry flag is set on return of either function then AX will contain an error code (and the file was not opened). Here is an example.
    :
    :
    : FileToOpen db '.MYFILE.TXT',0
    : OutputFile db '.MYFILEU.TXT',0
    : ReadFileHandle dw 0
    : WriteFileHandle dw 0
    :
    :
    : OpenForRead:
    :
    : mov ax,03D00h
    : int 021h
    : jc .Return
    : mov [ReadFileHandle],ax
    :
    : .Return:
    :
    : retn
    :
    :
    : OpenForWrite:
    :
    : mov ah,03Ch
    : xor cl,cl
    : int 021h
    : jc .Return
    : mov [WriteFileHandle],ax
    :
    : .Return:
    :
    : retn
    :
    :
    : A file handle is required to be able to access a file in DOS. It tells DOS what file to access. This needs to be saved for later use. After you are done with a file it is best to close it. Using AH = 04Ch to exit the program will close all files but this is bad programming practice. The file handle needs to be sent to function 03Eh so it knows which file to close. If the carry flag is set when this function returns then there was an error closing the file. If so, you should recall the function. BX needs to already contain the file handle. Here is some code.
    :
    :
    : CloseFile:
    :
    : mov ah,03Eh
    : retn
    :
    :
    : To read and write to files, you just need to call functions 03Fh and 040h of interrupt 021h. BX contains the file handle an CX the number of bytes to read/write from the file. DS:DX points to the location in memory to read/write the data to/from. On return, AX will contain the amount of bytes that actually were read/written. For reading if this was less than you requested then the end of file was found. Once again, if CF is set then there was an error.
    :
    :
    : ReadFromFile:
    :
    : mov ah,03Fh
    : mov bx,[ReadFileHandle]
    : int 021h
    : retn
    :
    :
    : WriteToFile:
    :
    : mov ah,040h
    : mov bx,[WriteFileHandle]
    : int 021h
    : retn
    :
    :
    : Here is what you could use for a main loop. I have tested this code and it works fine.
    :
    :
    : MainCode:
    :
    : mov ax,cs
    : ;mov ds,ax
    : mov dx,FileToOpen
    : call OpenForRead
    : jc .OpenReadError
    : mov dx,OutputFile
    : call OpenForWrite
    : jc .OpenWriteError
    :
    : .ReadConvertWrite:
    :
    : mov dx,Buffer
    : mov cx,16
    : call ReadFromFile
    : jc .ErrorReading
    : mov si,Buffer
    : mov cx,ax
    : jcxz .Done
    :
    : .ConvertByte:
    :
    : call ConvertCharacter
    : inc si
    : loop .ConvertByte
    :
    : mov cx,ax
    : mov dx,Buffer
    : call WriteToFile
    : jc .ErrorWriting
    : test ax,ax
    : jnz .ReadConvertWrite
    :
    : .Done:
    :
    : mov bx,[ReadFileHandle]
    : call CloseFile
    : mov bx,[WriteFileHandle]
    : call CloseFile
    : mov ax,04C00h
    : int 021h
    :
    : .OpenReadError:
    :
    : mov ah,9
    : mov dx,OpenReadError
    : int 021h
    : jmp .Done
    :
    : .OpenWriteError:
    :
    : mov ah,9
    : mov dx,OpenWriteError
    : int 021h
    : jmp .Done
    :
    : .ErrorReading:
    :
    : mov ah,9
    : mov dx,ReadError
    : int 021h
    : jmp .Done
    :
    : .ErrorWriting:
    :
    : mov ah,9
    : mov cx,WriteError
    : int 021h
    : jmp .Done
    :
    :
    : Buffer dw 0,0,0,0,0,0,0,0
    : OpenReadError db 'Error opening input!',10,13,'$'
    : OpenWriteError db 'Error opening output!',10,13,'$'
    : ReadError db 'Error reading input!',10,13,'$'
    : WriteError db 'Error writing output!',10,13,'$'
    :
    :
    : Michael Gallagher
    : asmosprog@hotmail.com
    :


    thank a lot to u...michael gallagher.
    I will tell you the result when I test this program.

    theozis


  • korkor Member Posts: 198
    It's a lot simpler than that, actually.
    The difference between a capital letter and a lowercase letter is 1 bit, specifically the 6th most significant bit. You'd just need to or every letter with 100000b. The letters are all between 41h and 5ah, for caps, and 61h and 7ah for lower case.

    To check (in nasm):

    mov al, byte [char]
    cmp al, 5ah ;if it's greater, it's caps, no need to modify
    jg alreadycaps lt;ink that's jump if greater than
    cmp al, 41h ;if less than, it's not a letter
    jl alreadycaps ;think that's jump if less than
    cmp al, 5ah
    jg alreadycaps
    or al, 20h
    mov byte [char], al
    alreadycaps

    ;all done

  • theozistheozis Member Posts: 4
    [b][red]This message was edited by theozis at 2003-2-19 22:38:52[/red][/b][hr]
    ok,thank a lot to all of ur help.

    But, i have try many times and the turbo assembler tell me that it have many bug.

    so,I hope u can write out the full sourcecode program.

    example:
    1.My file is locate at c: heozis.txt and it contain this sentence:
    I am a student.

    2.Then, the program open the file and edit it to like this:
    I AM A STUDENT.

    3.After that, the file save to original file and exit.

    here is the program sourcecode i edit from michael one

    DATA SEGMENT
    FileToOpen db 'C:Program FilesTurbo Assembleryinvei.txt'
    OutputFile db 'C:Program FilesTurbo Assembleryinveiu.txt',0
    ReadFileHandle dw 0
    WriteFileHandle dw 0
    Buffer dw 0,0,0,0,0,0,0,0
    OpenReadError db 'Error opening input!',10,13,'$'
    OpenWriteError db 'Error opening output!',10,13,'$'
    ReadError db 'Error reading input!',10,13,'$'
    WriteError db 'Error writing output!',10,13,'$' ;10
    DATA ENDS

    CODE SEGMENT 'CODE'
    ASSUME CS:CODE,DS:DATA


    MainCode:

    mov ax,cs
    ;mov ds,ax ;20
    mov dx,FileToOpen
    call OpenForRead
    jc .OpenReadError
    mov dx,OutputFile
    call OpenForWrite
    jc .OpenWriteError

    .ReadConvertWrite:

    mov dx,Buffer ;30
    mov cx,16
    call ReadFromFile
    jc .ErrorReading
    mov si,Buffer
    mov cx,ax
    jcxz .Done

    .ConvertByte:

    call ConvertCharacter ;40
    inc si
    loop .ConvertByte

    mov cx,ax
    mov dx,Buffer
    call WriteToFile
    jc .ErrorWriting
    test ax,ax
    jnz .ReadConvertWrite
    ;50
    .Done:

    mov bx,[ReadFileHandle]
    call CloseFile
    mov bx,[WriteFileHandle]
    call CloseFile
    mov ax,04C00h
    int 021h

    .OpenReadError: ;60

    mov ah,9
    mov dx,OpenReadError
    int 021h
    jmp .Done

    .OpenWriteError:

    mov ah,9
    mov dx,OpenWriteError ;70
    int 021h
    jmp .Done

    .ErrorReading:

    mov ah,9
    mov dx,ReadError
    int 021h
    jmp .Done
    ;80
    .ErrorWriting:

    mov ah,9
    mov cx,WriteError
    int 021h
    jmp .Done

    ConvertCharacter:

    push ax
    mov al,[si]
    cmp al,'a'
    jb .DoneConvert
    cmp al,'z'
    ja .DoneConvert
    sub al,020h
    mov [si],al

    .DoneConvert:

    pop ax
    retn

    OpenForRead:

    mov ax,03D00h
    int 021h
    jc .Return
    mov [ReadFileHandle],ax

    OpenForWrite:

    mov ah,03Ch
    xor cl,cl
    int 021h
    jc .Return
    mov [WriteFileHandle],ax

    .Return:

    retn

    ReadFromFile:

    mov ah,03Fh
    mov bx,[ReadFileHandle]
    int 021h
    retn

    WriteToFile:

    mov ah,040h
    mov bx,[WriteFileHandle]
    int 021h
    retn

    CloseFile:

    mov ah,03Eh
    retn


    CODE ENDS
    END


    then, i run this in turbo assembler and it tell me that operand types do not macth.

    i hope u can help me to edit it and paste the right code at here.

    thank you.


  • bigmike500bigmike500 Member Posts: 24
    hi theozis,
    i have taken a look at the code that you posted and the problem was that when you where referencing to your data strings you where not giving the interupt the value of the starting address of the string, i think! ;), i am a newbie to so that reason could be a load of bull so if i am wrong please set me correct. anyway it works and all you need to do is to change places that you have 'mov dx,FileToOpen' to 'mov dx,offset [FileToOpen]', ( have marked the places with *********************). also i have put your code in a slightly different format as i could not get the original to link, but the original assembles just fine and should work, (by the way i used tasm 5). hope it helps
    Mike

    .model small
    .stack
    .data

    FileToOpen db 'C: est.txt',0
    OutputFile db 'C: est1.txt',0
    ReadFileHandle dw 0
    WriteFileHandle dw 0
    Buffer dw 0,0,0,0,0,0,0,0
    OpenReadError db "Error opening input!",10,13,"$"
    OpenWriteError db "Error opening output!",10,13,"$"
    ReadError db "Error reading input!",10,13,"$"
    WriteError db "Error writing output!",10,13,"$" ;10
    anykey db "Changes have been made!!!" ,10,13,"press any key to contiune","$"



    .code
    MainCode:

    mov ax, @DATA
    mov ds, ax


    mov dx,offset [FileToOpen] ;******************************
    call OpenForRead
    jc .OpenReadError
    mov dx, offset [OutputFile] ;*****************************
    call OpenForWrite
    jc .OpenWriteError

    .ReadConvertWrite:

    mov dx,Buffer ;30
    mov cx,16
    call ReadFromFile
    jc .ErrorReading
    mov si,Buffer
    mov cx,ax
    jcxz .Done

    .ConvertByte:

    call ConvertCharacter ;40
    inc si
    loop .ConvertByte

    mov cx,ax
    mov dx,Buffer
    call WriteToFile
    jc .ErrorWriting
    test ax,ax
    jnz .ReadConvertWrite
    ;50
    .Done:

    mov bx,[ReadFileHandle]
    call CloseFile
    mov bx,[WriteFileHandle]
    call CloseFile

    mov ax,0900h ;dispay the anykey prompt
    mov dx,offset [anykey]
    int 21h

    xor ax,ax ; Get a key - store it in AX
    INT 16h ;this is like 'press any key to continue'

    mov ax,04C00h
    int 021h

    .OpenReadError: ;60

    mov ah,9
    mov dx,offset [OpenReadError] ;************************************
    int 021h
    jmp .Done

    .OpenWriteError:

    mov ah,9
    mov dx,offset [OpenWriteError] ;*********************************'
    int 021h
    jmp .Done

    .ErrorReading:

    mov ah,9
    mov dx,offset [ReadError] ;**************************************
    int 021h
    jmp .Done
    ;80
    .ErrorWriting:

    mov ah,9
    mov cx,offset [WriteError] ;**************************************
    int 021h
    jmp .Done

    ConvertCharacter:

    push ax
    mov al,[si]
    cmp al,'a'
    jb .DoneConvert
    cmp al,'z'
    ja .DoneConvert
    sub al,020h
    mov [si],al

    .DoneConvert:

    pop ax
    retn

    OpenForRead:

    mov ax,03D00h
    int 021h
    jc .Return
    mov [ReadFileHandle],ax
    retn ;<-added by me, not really needed

    OpenForWrite:

    mov ah,03Ch
    xor cx,cx ;<-need to clear the whole of cx
    int 021h
    jc .Return
    mov [WriteFileHandle],ax

    .Return:

    retn

    ReadFromFile:

    mov ah,03Fh
    mov bx,[ReadFileHandle]
    int 021h
    retn

    WriteToFile:

    mov ah,040h
    mov bx,[WriteFileHandle]
    int 021h
    retn

    CloseFile:

    mov ah,03Eh
    int 021h ;<- need to call the interrupt
    retn


    END MainCode
  • asmosprogasmosprog Member Posts: 54
    : hi theozis,
    : i have taken a look at the code that you posted and the problem was that when you where referencing to your data strings you where not giving the interupt the value of the starting address of the string, i think! ;), i am a newbie to so that reason could be a load of bull so if i am wrong please set me correct. anyway it works and all you need to do is to change places that you have 'mov dx,FileToOpen' to 'mov dx,offset [FileToOpen]', ( have marked the places with *********************). also i have put your code in a slightly different format as i could not get the original to link, but the original assembles just fine and should work, (by the way i used tasm 5). hope it helps
    : Mike
    :
    : .model small
    : .stack
    : .data
    :
    : FileToOpen db 'C: est.txt',0
    : OutputFile db 'C: est1.txt',0
    : ReadFileHandle dw 0
    : WriteFileHandle dw 0
    : Buffer dw 0,0,0,0,0,0,0,0
    : OpenReadError db "Error opening input!",10,13,"$"
    : OpenWriteError db "Error opening output!",10,13,"$"
    : ReadError db "Error reading input!",10,13,"$"
    : WriteError db "Error writing output!",10,13,"$" ;10
    : anykey db "Changes have been made!!!" ,10,13,"press any key to contiune","$"
    :
    :
    :
    : .code
    : MainCode:
    :
    : mov ax, @DATA
    : mov ds, ax
    :
    :
    : mov dx,offset [FileToOpen] ;******************************
    : call OpenForRead
    : jc .OpenReadError
    : mov dx, offset [OutputFile] ;*****************************
    : call OpenForWrite
    : jc .OpenWriteError
    :
    : .ReadConvertWrite:
    :
    : mov dx,Buffer ;30
    : mov cx,16
    : call ReadFromFile
    : jc .ErrorReading
    : mov si,Buffer
    : mov cx,ax
    : jcxz .Done
    :
    : .ConvertByte:
    :
    : call ConvertCharacter ;40
    : inc si
    : loop .ConvertByte
    :
    : mov cx,ax
    : mov dx,Buffer
    : call WriteToFile
    : jc .ErrorWriting
    : test ax,ax
    : jnz .ReadConvertWrite
    : ;50
    : .Done:
    :
    : mov bx,[ReadFileHandle]
    : call CloseFile
    : mov bx,[WriteFileHandle]
    : call CloseFile
    :
    : mov ax,0900h ;dispay the anykey prompt
    : mov dx,offset [anykey]
    : int 21h
    :
    : xor ax,ax ; Get a key - store it in AX
    : INT 16h ;this is like 'press any key to continue'
    :
    : mov ax,04C00h
    : int 021h
    :
    : .OpenReadError: ;60
    :
    : mov ah,9
    : mov dx,offset [OpenReadError] ;************************************
    : int 021h
    : jmp .Done
    :
    : .OpenWriteError:
    :
    : mov ah,9
    : mov dx,offset [OpenWriteError] ;*********************************'
    : int 021h
    : jmp .Done
    :
    : .ErrorReading:
    :
    : mov ah,9
    : mov dx,offset [ReadError] ;**************************************
    : int 021h
    : jmp .Done
    : ;80
    : .ErrorWriting:
    :
    : mov ah,9
    : mov cx,offset [WriteError] ;**************************************
    : int 021h
    : jmp .Done
    :
    : ConvertCharacter:
    :
    : push ax
    : mov al,[si]
    : cmp al,'a'
    : jb .DoneConvert
    : cmp al,'z'
    : ja .DoneConvert
    : sub al,020h
    : mov [si],al
    :
    : .DoneConvert:
    :
    : pop ax
    : retn
    :
    : OpenForRead:
    :
    : mov ax,03D00h
    : int 021h
    : jc .Return
    : mov [ReadFileHandle],ax
    : retn ;<-added by me, not really needed
    :
    : OpenForWrite:
    :
    : mov ah,03Ch
    : xor cx,cx ;<-need to clear the whole of cx
    : int 021h
    : jc .Return
    : mov [WriteFileHandle],ax
    :
    : .Return:
    :
    : retn
    :
    : ReadFromFile:
    :
    : mov ah,03Fh
    : mov bx,[ReadFileHandle]
    : int 021h
    : retn
    :
    : WriteToFile:
    :
    : mov ah,040h
    : mov bx,[WriteFileHandle]
    : int 021h
    : retn
    :
    : CloseFile:
    :
    : mov ah,03Eh
    : int 021h ;<- need to call the interrupt
    : retn
    :
    :
    : END MainCode
    :


    Hello,

    The reason that MOV DX,OFFSET [FileToOpen] was not used is because I wrote that code using FASM. In FASM, using MOV DX,FileToOpen will move the offset of the label into DX and MOV DX,[FileToOpen] will move the WORD at that offset into DX.

    Michael Gallagher
    asmosprog@hotmail.com
  • theozistheozis Member Posts: 4
    halo, thank a lot, michael and mike, the program already can run fine...
Sign In or Register to comment.