Lesson 3 of 48 beginner

Number Systems: Binary, Decimal, Hex

Speaking the native language of digital circuits

Open interactive version (quiz + challenge)

Real-world analogy

Number systems are like different languages for the same ideas. Decimal is your everyday English -- comfortable for humans. Binary is Morse code -- only dots and dashes (0s and 1s), perfect for simple on/off circuits. Hexadecimal is shorthand -- like abbreviations that compress four binary digits into a single character so engineers can read long binary values without going cross-eyed.

What is it?

Number systems are methods of representing numeric values using different bases. Binary (base-2) is the fundamental language of digital circuits using only 0 and 1. Decimal (base-10) is the human-friendly system. Hexadecimal (base-16) is the engineer's shorthand that compresses binary into a compact, readable format used universally in assembly programming, memory addresses, and hardware debugging.

Real-world relevance

When you see a MAC address like 3C:A6:F6:12:E4:8B on your network adapter, those are hexadecimal values. When a blue screen of death shows an error code like 0x0000007E, that is hex. When a color code #D9FE06 defines neon green in CSS, each pair of hex digits represents a binary value for red, green, and blue intensity.

Key points

Code example

; 8086 Assembly: Convert a binary nibble (0-15) to its ASCII hex character
; Input: DL = value 0-15
; Output: DL = ASCII character '0'-'9' or 'A'-'F'

.MODEL SMALL
.STACK 100h
.CODE
MAIN PROC
  MOV AX, @DATA
  MOV DS, AX

  MOV DL, 0Bh         ; Test value: 11 decimal = 'B' in hex

  CMP DL, 09h          ; Is it 0-9 or A-F?
  JBE IS_DIGIT          ; Jump if DL <= 9

  ADD DL, 37h          ; 0Ah + 37h = 41h = 'A'
  JMP PRINT             ;  0Bh + 37h = 42h = 'B', etc.

IS_DIGIT:
  ADD DL, 30h          ; 00h + 30h = 30h = '0'
                       ; 09h + 30h = 39h = '9'

PRINT:
  MOV AH, 02h          ; DOS print character function
  INT 21h              ; Print the hex character

  MOV AH, 4Ch
  INT 21h
MAIN ENDP
END MAIN

Line-by-line walkthrough

  1. 1. MOV DL, 0Bh -- We load our test value (11 decimal, which should produce the character 'B') into the DL register.
  2. 2. CMP DL, 09h -- Compares DL with 9. This determines whether our nibble is a digit (0-9) or a letter (A-F). CMP sets flags without changing DL.
  3. 3. JBE IS_DIGIT -- 'Jump if Below or Equal.' If DL is 0-9, we jump to the digit handling code. JBE checks the Carry and Zero flags set by CMP.
  4. 4. ADD DL, 37h -- For values A-F (10-15): adding 37h converts to ASCII. For example, 0Ah (10) + 37h = 41h which is ASCII 'A'. This works because 'A' is at position 41h in the ASCII table.
  5. 5. ADD DL, 30h -- For values 0-9: adding 30h converts to ASCII. For example, 05h + 30h = 35h which is ASCII '5'. The digit '0' starts at position 30h in ASCII.
  6. 6. MOV AH, 02h / INT 21h -- DOS function 02h prints the character in DL to the screen. INT 21h invokes the DOS interrupt handler.

Spot the bug

MOV AL, 29h
ADD AL, 18h
DAA
; Expected: BCD 47, Got: something wrong
Need a hint?
Check if the ADD result before DAA is correct and whether both operands are valid BCD values.
Show answer
The value 18h is not valid BCD -- the digit 8 is fine but together '18' in BCD should represent eighteen, which would be 18h. Actually the real issue is that 29h + 18h = 41h, and DAA adjusts to 47h. The bug is the comment: the expected answer should be 47, and the code actually works correctly! This is a trick question -- always verify your assumptions before 'fixing' working code.

Explain like I'm 5

Imagine you only have two fingers -- that is binary, and you can count from 0 to 1. Now imagine you have ten fingers -- that is decimal, counting from 0 to 9. Now imagine you're an alien with sixteen fingers -- that is hexadecimal, counting from 0 to F. Computers only have 'two fingers' (on and off), but engineers use the 'sixteen finger' system to write things faster without making mistakes.

Fun fact

The word 'DEADBEEF' is a famous hexadecimal constant (0xDEADBEEF) used as a magic debug value in many systems. IBM RS/6000 used it, and it appears in Java class files. Other fun hex words engineers have used: 0xCAFEBABE (Java class magic number), 0xBAADF00D (Windows debug fill), and 0xFEEDFACE (Mach-O binaries on macOS).

Hands-on challenge

Convert the following values by hand (then verify with assembly code): (a) Decimal 200 to binary and hex. (b) Hex 0x3F7A to binary and decimal. (c) Binary 10110011 to hex and decimal. (d) What is -42 in 8-bit two's complement (binary and hex)?

More resources

Open interactive version (quiz + challenge) ← Back to course: Microprocessor A–Z