Changing a single bit (Decode program)?

Started by shagywashere, October 20, 2011, 02:18:31 AM

Previous topic - Next topic

shagywashere

Writing a decode program, find the take a number, find the bad bit (out of 11 bits) and then change the bad bit to the opposite (0 if 1; 1 if 0) then encode the message. The Parity procedure (not posted here) just returns the count of 1's in a certain pattern.

I have it to where I can find the bad bit, but I don't know how to change (toggle) the bit. Say the bad bit is 5, how would I change bit 5? The bad bit is different dependin on the number

;===================================================================
;                   DECODE.ASM
;===================================================================
         EXTRN  GETDEC$:FAR
         EXTRN  NEWLINE:FAR
         EXTRN  PUTSTRNG:FAR
         EXTRN  PUTDEC$:FAR
EXTRN PUTBIN:FAR
EXTRN PUTOCT:FAR
EXTRN PAUSE:FAR
         EXTRN  PARITY:FAR
;===================================================================
        .MODEL  SMALL, BASIC
        .STACK  256
;===================================================================
; D A T A   S E G M E N T   D E F I N I T I O N
        .DATA
NUMBER DW  ?
TEMP DW ?
ENCODEDNUM DW  ?
BADBIT DW ?
GRP8 DW ?
GRP4 DW ?
GRP2 DW ?
GRP1 DW ?
AUTHOR DB  'Programmed By *.'
PROMPT DB 'Enter a number: '
BINDISPLAY DB 'Number in binary: '
ENCDISPLAY DB 'Number in binary (data bits set in place): '
PKTDISPLAY DB 'Encoded packet in binary: '
PKTOCTDISPLAY DB 'Encoded packet in octal: '
OCTDISPLAY DB 'Number in octal: '
ONESDISPLAY DB 'Number of 1s: '
BADDISPLAY DB 'Bad bit is: '
EVENDISPLAY DB 'The number of 1s is even. '
;===================================================================
; C O D E   S E G M E N T   D E F I N I T I O N
        .CODE
        ASSUME  DS:DGROUP
;===================================================================
;1 2 3 4 5 6 7 8 9 10 11
;GROUP 1: 1 3 5 7 9 11
;GROUP 2: 2 3 6 7 10 11
;GROUP 3: 4 5 6 7
;GROUP 4; 8 9 10 11

MAIN    PROC

        MOV     AX,DGROUP           ;SET DS-REGISTER TO POINT TO
        MOV     DS,AX               ;DATA SEGMENT
        MOV     ES,AX               ;AND ES ALSO
MOV TEMP, 0
MOV BADBIT, 0
MOV BL, 1
        CALL    NEWLINE
        LEA DI, PROMPT
        MOV     CX, SIZEOF PROMPT
        CALL    PUTSTRNG
        CALL    GETDEC$
        MOV TEMP, AX
CALL NEWLINE
LEA DI, OCTDISPLAY
MOV CX, SIZEOF OCTDISPLAY
CALL PUTSTRNG
CALL PUTOCT
        CALL    NEWLINE
        LEA     DI, BINDISPLAY
        MOV     CX, SIZEOF BINDISPLAY
        CALL    PUTSTRNG
CALL PUTBIN

MASKGRPS:
AND AX, 00000001111B
CALL PARITY
AND AX, 0001B
.IF AX == 1
ADD BADBIT, 1000B
.ENDIF
MOV AX, TEMP
AND AX, 00011110000B
CALL PARITY
AND AX, 0001B
.IF AX == 1
ADD BADBIT, 0100B
.ENDIF
MOV AX, TEMP
AND AX, 01100110011B
CALL PARITY
AND AX, 0001B
.IF AX == 1
ADD BADBIT, 0010B
.ENDIF
MOV AX, TEMP
AND AX, 10101010101B
CALL PARITY
AND AX, 0001B
.IF AX == 1
ADD BADBIT, 0001B
.ENDIF
;MOV AX, TEMP
;MOV CX, BADBIT
;SHR AX, CL

CALL NEWLINE
CALL NEWLINE
LEA DI, BADDISPLAY
MOV CX, SIZEOF BADDISPLAY
CALL PUTSTRNG
MOV AX, BADBIT
CALL PUTDEC$

QUIT:
LEA     DI, AUTHOR
        MOV     CX, SIZEOF AUTHOR
CALL NEWLINE
CALL NEWLINE
CALL PUTSTRNG
SUB CX, CX ;If you don't do this, AUTHOR will be printed twice.
CALL PAUSE
.EXIT
        MOV     AX, 4C00H
        INT     21H
MAIN    ENDP
        END MAIN       

dedndave

well, here is one way
there is probably something more efficient   :P
        mov     cl,BitToToggle   ;(0 to 15)
        mov     dx,1
        mov     ax,ValueToFix
        shl     dx,cl
        xor     ax,dx

shagywashere

I did it

      
                MOV AX, BADBIT
.IF AX > 0000B
MOV AX, 11
SUB AX, BADBIT
MOV CX, AX
MOV AX, TOGGLE
SHL AX, CL
MOV TOGGLE, AX
MOV AX, TEMP
XOR AX, TOGGLE
MOV TEMP, AX
.ENDIF

dedndave

i would probably re-write the loop so that the shift count came out in CX "naturally"


dedndave

attach your program as a ZIP file
(below the reply window - Additional Options)

and i will show you

shagywashere

Perfect, because it's already zipped up (that's how we turn it in). There's a document file in there, you can just ignore that. DEC.BAT compiles it for you

dedndave

ok - it doesn't look like there is any way to return the value in CX naturally
that is because you use CL to hold shift counts in the ENCODE routine

there are many ways to speed things up a bit, however
and - you probably aren't too concerned about speed

one thing for sure....
in 16-bit code, SHL AX,CL is relatively slow - at least, compared to SHL AX,1
when you shift a word register by 1, it is a 2-byte instruction and it takes 2 clock cycles on an 8088
not sure how these 16-bit instructions time on newer machines - haven't played with it, much

i only mention it because i happened to see this code
MOV CL, 2
SHL AX, CL

in 16-bit world, you may as well use 2 SHL AX,1 instructions - same size, only faster
SHL             AX, 1
SHL AX, 1