Convert Character to binary assembly language
Asked Answered
Z

2

0

Hi i m using dosbox and masm compilor. I want to prompts the user to enter a character, and prints the ASCII code of the character in hex and in binary on the next line. Repeat this process untill the user types a carriage return. The following code work fine to display the charcters in hexadecimal until a carriage return how can i modify this code to display the binary of charcter as well.?

 .MODEL SMALL
 .STACK 100H

  .DATA
   PROMPT_1  DB  0DH,0AH,'Enter the character : $'
   PROMPT_2  DB  0DH,0AH,'The ASCII code of the given number in HEX       form     is : $'

 .CODE
  MAIN PROC
 MOV AX, @DATA                ; initialize DS  
 MOV DS, AX

 @START:                      ; jump label 
   LEA DX, PROMPT_1           ; load and display the string PROMPT_1
   MOV AH, 9
   INT 21H

   MOV AH, 1                  ; read a character
   INT 21H

   MOV BL, AL                 ; move AL to BL

   CMP BL, 0DH                ; compare BL with CR
   JE @END                    ; jump to label @END if BL=CR

   LEA DX, PROMPT_2           ; load and display the string PROMPT_2
   MOV AH, 9
   INT 21H

   XOR DX, DX                 ; clear DX
   MOV CX, 4                  ; move 4 to CX

   @LOOP_1:                   ; loop label
     SHL BL, 1                ; shift BL towards left by 1 position
     RCL DL, 1                ; rotate DL towards left by 1 position
                              ; through carry
   LOOP @LOOP_1               ; jump to label @LOOP_1 if CX!=0

   MOV CX, 4                  ; move 4 to CX

   @LOOP_2:                   ; loop label
     SHL BL, 1                ; shift BL towards left by 1 position
     RCL DH, 1                ; rotate DH towards left by 1 position
                              ; through carry
   LOOP @LOOP_2               ; jump to label @LOOP_2 if CX!=0

   MOV BX, DX                 ; move DX to BX
   MOV CX, 2                  ; initialize loop counter

   @LOOP_3:                   ; loop label
     CMP CX, 1                ; compare CX wiht 1
     JE @SECOND_DIGIT         ; jump to label @SECOND_DIGIT if CX=1
     MOV DL, BL               ; move BL to DL
     JMP @NEXT                ; jump to label @NEXT

     @SECOND_DIGIT:           ; jump label
       MOV DL, BH             ; move BH to DL

     @NEXT:                   ; jump label

     MOV AH, 2                ; set output function

     CMP DL, 9                ; compare DL with 9
     JBE @NUMERIC_DIGIT       ; jump to label @NUMERIC_DIGIT if DL<=9
     SUB DL, 9                ; convert it to number i.e. 1,2,3,4,5,6
     OR DL, 40H               ; convert number to letter i.e. A,B...F
     JMP @DISPLAY             ; jump to label @DISPLAY

     @NUMERIC_DIGIT:          ; jump label
       OR DL, 30H             ; convert decimal to ascii code

     @DISPLAY:                ; jump label
       INT 21H                ; print the character
   LOOP @LOOP_3               ; jump to label @LOOP_3 if CX!=0

   JMP @START                 ; jump to label @START

 @END:                        ; jump label

 MOV AH, 4CH                  ; return control to DOS
 INT 21H
 MAIN ENDP
 END MAIN
Zagreb answered 23/11, 2016 at 16:35 Comment(4)
can anyone help plz?Zagreb
Use succesive divisions by 2, that gives you binary, example : '0' char is 48 (or 30h), so : 48÷2=24 (remainder 0), 24÷2=12 (remainder 0), 12÷2=6 (remainder 0), 6÷2=3 (remainder 0), 3÷2=1 (remainder 1), 1÷2=0 (remainder 1). Now take the remainders starting from the last one = 110000 .Alkalize
@ jose can u plz correct my code .Zagreb
@JoseManuelAbarcaRodríguez she has the value already in AL after int 21h .. so it already is in "binary" form in those AL bits. No need to convert it in any way, you can work with bits on x86. I think this is important milestone in asm programmer thinking, to realize *what* is actually inside CPU, so she can exploit it later to write simpler code. Doing this by div 2 is possible, but many kittens would be killed in the process (I don't care) and my eyes would hurt a lot (this one I do mind).Galeiform
G
2

When you have the value in register, it is stored in CPU in bits (0/1 encoded as low/high current voltage), so it's actually "formatted" in binary!

You just need to output eight characters '0'/'1' per bit, starting from most significant one.

At the moment where you have the character in AL, the code to output the binary form may look like this:

    cx = 8   ; 8 bits to output
bin_loop:
    rcl al,1 ; move most significant bit into CF
    setc bl  ; bl = 0 or 1 by CF (80386 instruction)
    add bl,'0' ; turn that 0/1 into '0'/'1' ASCII char
    call display_bl ; must preserve al and cx
    loop bin_loop

Judging by your usage of cx for loop you are in 16b real mode. So if you also can't use 80386 instructions (setc) (when targetting 8086/80186/80286 CPU, like emu8086 emulator), then this can be achieved in other way (like two instructions for example, instead of one).

From your usage of CF in those loops with shl/rcl I'm sure you will figure something out, it's very similar.

Galeiform answered 23/11, 2016 at 17:9 Comment(11)
can u plz edit my code to work for binary as well. Now m too much tired dont understand this now :(Zagreb
@Zagreb no, I don't have 16b x86 ASM environment around, so I wouldn't be able to verify if my changes works correctly. And I'm not sure where you want that output (Ahead/after hexa? With some prefix/suffix indicating binary form like "0b" prefix in C++?). If you will try it on your own, and post the second version of your source, I may take a quick look to see if I spot any problem. BTW your current source can be simplified considerably, and you should try, so you get better understanding of x86 ASM in the process. If you are tired, get some rest, then return to it.Galeiform
Can u do ur changes without verification. Yes i can do it later but i have to compete it within an hourZagreb
now I see the question does specify the format of output (next line under hex), so at least this one is clear. So push ax after reading char, then use your current code to output hex number, then output new line string (define new "prompt" one with only 13,10,'$'), then pop the char value into desired register (my loop is using al, so pop ax will do), and run my loop to output binary form. About changes: no, you are wasting your time by discussing this. Write your own answer with something you tried, note how it behaves when run (if it works), I will take a look on it then.Galeiform
it would be a great favor if u can change my code without verificationZagreb
@Zagreb well, from my answer and comments it's almost ready for copy/paste ... try it, you have still 30+ minutes to put such try here and then hope I will review it in time, or that you will make it work. It boils down how much of your current code you already understand. If you just gathered some code here and there and made it work by luck, then I'm afraid you will fail. If you understand basics what the instructions do, you should be able to figure out my comments within 30min easily. (if you plan to use that ah=2 output char, I would change bl in my loop to dl, al is preserved (OK)).Galeiform
somethings i dont understand but my seniors and teachesr dont help me thats why m asking otherwise yes i will fail :(Zagreb
@Zagreb let me know if you failed. :) (I'm just emotional vampire, evil one) Pity you don't have more time, to post some particular detailed intelligent questions about things you don't understand... If you would have like 1-2 weeks, I'm sure we would be able to sort it out, basics of ASM are not that complicated. But it requires lot of focus and dedication. (BTW if you did try to edit it on your own, sometimes around "now" I would expect second version of code posted).Galeiform
@Galeiform I'm glad you had a mature attitude and didn't post the full code :) As the OP is in no way willing to learn, posting a complete solution just equates to helping people to cheat on exams.Peptide
@MargaretBloom ty, but attributing me "mature attitude" is stretching it too far, now I'm tempted to write you something extremely stupid to even it out :). What really annoys me is the OP looks like in few hours or couple of days it would be possible to get her several levels up in ASM (unless that original code is already fraud). It's pity to stop half way there and waste all that initial investment. Also I'm tiny bit annoyed by Jose posting inefficient non-elegant solutions, but I respect his effort to help, so +1 -1 = +-0 from me (but I see somebody else had more twitching finger).Galeiform
@MargaretBloom, no hard feelings, we are all used to how StackOverflow is and works. We all have our own points of view, that's what makes it fun, we are all different. About cheating . . . well, anything goes!Alkalize
A
1

Ok, Sarah, I made the changes to your code, now it displays binary, I added two variables, all the changes are pointed by little ◄■ arrows :

 .MODEL SMALL
 .STACK 100H

  .DATA
   PROMPT_1  DB  0DH,0AH,'Enter the character : $'
   PROMPT_2  DB  0DH,0AH,'The ASCII code of the given number in HEX       form     is : $'
   PROMPT_3  DB  0DH,0AH,'The ASCII code of the given number in BIN       form     is : $'
   MY_CHAR   DB  ?          ; ◄■ char entered by user.
   BINARY    DB  9 DUP('$') ; ◄■ zeroes and ones.

 .CODE
  MAIN PROC
 MOV AX, @DATA                ; initialize DS  
 MOV DS, AX

 @START:                      ; jump label 
   LEA DX, PROMPT_1           ; load and display the string PROMPT_1
   MOV AH, 9
   INT 21H

   MOV AH, 1                  ; read a character
   INT 21H                                      

   MOV MY_CHAR, AL ; ◄■ save char to use in binary conversion.
   MOV BL, AL                 ; move AL to BL

   CMP BL, 0DH                ; compare BL with CR
   JE @END                    ; jump to label @END if BL=CR

   LEA DX, PROMPT_2           ; load and display the string PROMPT_2
   MOV AH, 9
   INT 21H

   XOR DX, DX                 ; clear DX
   MOV CX, 4                  ; move 4 to CX

   @LOOP_1:                   ; loop label
     SHL BL, 1                ; shift BL towards left by 1 position
     RCL DL, 1                ; rotate DL towards left by 1 position
                              ; through carry
   LOOP @LOOP_1               ; jump to label @LOOP_1 if CX!=0

   MOV CX, 4                  ; move 4 to CX

   @LOOP_2:                   ; loop label
     SHL BL, 1                ; shift BL towards left by 1 position
     RCL DH, 1                ; rotate DH towards left by 1 position
                              ; through carry
   LOOP @LOOP_2               ; jump to label @LOOP_2 if CX!=0

   MOV BX, DX                 ; move DX to BX
   MOV CX, 2                  ; initialize loop counter

   @LOOP_3:                   ; loop label
     CMP CX, 1                ; compare CX wiht 1
     JE @SECOND_DIGIT         ; jump to label @SECOND_DIGIT if CX=1
     MOV DL, BL               ; move BL to DL
     JMP @NEXT                ; jump to label @NEXT

     @SECOND_DIGIT:           ; jump label
       MOV DL, BH             ; move BH to DL

     @NEXT:                   ; jump label

     MOV AH, 2                ; set output function

     CMP DL, 9                ; compare DL with 9
     JBE @NUMERIC_DIGIT       ; jump to label @NUMERIC_DIGIT if DL<=9
     SUB DL, 9                ; convert it to number i.e. 1,2,3,4,5,6
     OR DL, 40H               ; convert number to letter i.e. A,B...F
     JMP @DISPLAY             ; jump to label @DISPLAY

     @NUMERIC_DIGIT:          ; jump label
       OR DL, 30H             ; convert decimal to ascii code

     @DISPLAY:                ; jump label
       INT 21H                ; print the character
   LOOP @LOOP_3               ; jump to label @LOOP_3 if CX!=0


;▼ FROM CHAR TO BINARY ▼
     LEA SI, BINARY+7 ; ◄■ point to string in data segment.
     MOV CX, 8        ; ◄■ maximum number of binary digits.
   @BIN_CONVERSION:
     SHR MY_CHAR,1    ; ◄■ get rightmost bit.
     JC  @BIT1
     MOV [BYTE PTR SI], '0'
     JMP @BIN_SKIP
   @BIT1:
     MOV [BYTE PTR SI], '1'
   @BIN_SKIP:
     DEC SI
     LOOP @BIN_CONVERSION

     LEA DX, PROMPT_3 ; ◄■ display message.
     MOV AH, 9
     INT 21H         
     LEA DX, BINARY   ; ◄■ display binary.
     MOV AH, 9
     INT 21H         

   JMP @START                 ; jump to label @START

 @END:                        ; jump label

 MOV AH, 4CH                  ; return control to DOS
 INT 21H
 MAIN ENDP
 END MAIN
Allocate answered 23/11, 2016 at 17:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.