following code is including a hexadecimal number (relevant to ASCII code assume that it is obtained from keyboard), I want to print this hex number to the screen but in "binary" using DOS Interrupt. NUMLOCK is 45h.
[org 0x0100]
mov AL, 45 ;moving NUMLOCK hexadecimal(ASCII code) to AX
~~How to display its binary relevant to screen using DOS Interrupt?
DOS Interrupt has only these services outputting to screen:
AH = 02h -WRITE CHARACTER TO STANDARD OUTPUT
AH = 06h - DIRECT CONSOLE OUTPUT
AH = 09h - WRITE STRING TO STANDARD OUTPUT
AH = 40h - "WRITE" - WRITE TO FILE OR DEVICE (when called with STDOUT or STDERR file handle)
All of these only copy the value from input to the output, without any conversions or formatting, so usually your input should be ASCII character or string, or binary byte array.
But you should understand, that computers work in binary (low current/high current, which is often interpreted as 0 or 1). It doesn't understand any other value.
So when you have value
69
in CPU registeral
, theal
is created from 8 bit cells on the CPU chip, and those cells are set as "0 1 0 0 0 1 0 1". The cells are called bits. So when you write in Assembly sourcemov al,45h
, the assembler during compilation creates this binary form for you, and stores it into machine code as single byte, because that's howmov al,imm8
instruction expects the value encoded.So all you have to do for "binary string" is to go bit by bit from left to right, 8 times, and output character
'0'
or'1'
to the screen, depending whether particular bit is clear, or set.If your task would be to display the number in any other base (for example base 10 = decimal), you would have to do complex calculation to find out particular digits
'6'
and'9'
forming the decimal format "69".Any base of power of two is a bit simpler, because you need just to extract group of bits (for example in hexadecimal base 16 every single digit is exactly 4 bits part of value, notice how
45h
is in binary0100
(4) and0101
(5). But you still have to calculate groups of bits.Only the binary base 2 output is basically ready to be printed, because that's the native way how computer stores numerical integer values in registers and memory.
It's absolutely crucial you realize what are bits, and what does it mean that
al
is 8 bit register, andax
is 16 bit register, andah
is upper 8 bits ofax
, etc... If you don't understand how binary math works, and how those values are encoded in bits, you will have hard time with very simple Assembly tasks, like this one.That's why I'm not even adding any code here, because you need first work out your math, to fully understand what "base N" encoding of value means.
After you will understand what the computer does work with, you will be very likely able to quickly check some bit-wise instructions like shifts or test, and do the bit check + output 0/1 to screen loop. It's very simple task, when you understand it.
EDIT: I decided to give you something more visual, I wrote "display binary 8 bit value" in the "Simple 8-bit Assembler".
It's not 8086, but:
Put the next code into page: http://schweigi.github.io/assembler-simulator/
And use "Step" to slowly go instruction by instruction and watch the "memory" and "register" views on right to see, what the instruction does (you can use x86 instruction reference guide to read what the instruction should do, I think all the descriptions will fit also this simple Assembler (although some are not 100% correct about flags, but you will not notice and better learn 8086 instructions from start)).
Then you can think how you can turn this into 8086 version.
I would suggest to turn the loop logic to go from top-most bit, it's easier with 8086, as you can use many more instructions, like
adc
(for example you can try to figure out, what is result ofmov dl,24
adc dl,dl
... it may be quite interesting aftershl
). Then you can output the digits directly byint 21h,2
(if you reverse the logic to test bits from left to right).Or you can keep the same logic, and store the ASCII digits into memory buffer from end (make sure you have big enough buffer), and the print it with single
int 21h, 9
.Or ... there are million other ways how to calculate the same result (outputting to screen "0100 0101" ASCII digits from original value
45h
). It's only about outputting correct number at correct place and time, how you calculate it doesn't matter, as long as your result is correct.