How to change bits in a char in TASM?

2019-07-27 13:09发布

问题:

I have to write a program which is reading chars from a file, changing bits in every char and writing changes to a new file in TASM.

I've written a program which is reading chars from a file and writing them to a new file, but I don't know how to change bits in a char.

For example, here would be my file with chars:

a       // 01100001
b       // 01100010
c       // 01100011
d       // 01100100

So, if we are changing first and second bit to 1, the output should be:

c       // 01100011
c       // 01100011
c       // 01100011
g       // 01100111

How to change bits in a char

Here's my code:

.model small
       ASSUME CS:code, DS:data, SS:stack

stack segment word stack 'STACK'
       dw 400h dup (00)               
stack ends

data segment para public 'DATA'

    ourFile:
       dw 0FFFh
    byteInFile:
       db 00, 00, ' $'
    handle:
       dw ?
    outputTextFile:
        db 'TEXTOUT.CSV',0
    inputTextFile:
        db 'TEXT.CSV',0

data ends

writeToFile macro byte
    push ax
    push bx
    push cx
    push dx

    mov ah, 40h
    mov bx, word ptr[handle]
    mov cx, 1
    int 21h

    pop dx
    pop cx
    pop bx
    pop ax
endm
LOCALS @@

code segment para public 'CODE'

openFile proc near
    push ax
    push dx

    mov ah, 3Dh
    mov al, 00h      
    int 21h

    jc @@end
    mov word ptr ourFile, ax

    @@end:
    pop dx
    pop ax
    ret
openFile endp


closeFile proc near
    push ax
    push bx

    mov ah, 3Eh
    int 21h

    @@end:
    pop dx
    pop ax
    ret
closeFile endp


readLinesInFile proc near  
    push ax
    push dx
    push bx
    push cx
    push si
    push di

    mov si, dx
    mov di, 0               
    @@repeat:
    mov cx, 01
    mov ah, 3Fh
    int 21h
    jc @@end           
    cmp ax, 00
    je @@end           

    // here we have to change chars' bit?


    // outputting chars
    push ax
    push dx
    mov dl, byte ptr[si]
    mov ah, 02h
    int 21h
    pop dx
    pop ax

    writeToFile byte ptr[si]

    jmp @@repeat
    @@end:
    pop di
    pop si
    pop cx
    pop bx
    pop dx
    pop ax
    ret
readLinesInFile endp

    begin:

       mov ax,     seg data                   
       mov ds,     ax


       mov si, offset outputTextFile 
       mov cl, [ si ] 
       mov ch, 0      
       inc cx         
       add si, cx     
       mov al, 0
       mov [ si ], al 

       ; We create file
       mov ah, 3ch
       mov cx, 0
       mov dx, offset outputTextFile
       int 21h
       ;  save handle
       mov word ptr[handle], ax

       ; We open file
       mov dx, offset  inputTextFile
       call openFile

       mov bx, word ptr ourFile
       mov dx, offset byteInFile
       call readLinesInFile

       ; We close file
       mov bx, word ptr ourFile
       call closeFile
       jmp @@Ok

       mov ah, 3Eh                         
       mov bx, word ptr[handle]                     
       int 21h

       @@Ok:
        mov ah,     4ch                            
        int 21h

code  ends
    end begin

回答1:

You can use instruction AND to set bits to 0, and instruction OR to set bits to 1, examples :

                     BIT 7    BIT 0
                        ▼      ▼
mov al, '9'   ;◄■■ AL = 00111001 (57).

Set the highest bit (7) in 1 and leave the others unchanged (with OR the 0s leave bits unchanged) :

                          BIT 7
        ▼                    ▼
or  al, 10000000b  ;◄■■ AL = 10111001

Now set the lowest bit (0) in 0 and leave the others unchanged (with AND the 1s leave bits unchanged) :

                                 BIT 0
               ▼                    ▼
and al, 11111110b  ;◄■■ AL = 10111000

Notice how each instruction is the opposite of the other, OR to set 1s, AND to set 0s, OR uses a mask of 0s, AND uses a mask of 1s.

You ask how to change first (0) and second (1) bits at a time :

                                  ▼▼
mov al, 'a'       ;◄■■ AL = 01100001
or  al, 00000011b ;◄■■ AL = 01100011
              ▲▲                  ▲▲

Again, notice how OR uses a mask of 0s to leave the other bits unchanged. Also notice the "b" at the end of the binary numbers.

Finally, in your code you are reading only one byte at a time from file, this byte is stored in variable byteInFile, so :

// here we have to change chars' bit?
  or byteInFile, 00000011b     ;◄■■ SET BITS 0 AND 1, LEAVE THE REST UNCHANGED.