YouTip LogoYouTip

Assembly Numbers

Assembly Language - Number Processing

In assembly language, handling numbers involves a combination of base conversion, ASCII conversion, and arithmetic operations. This chapter explains in detail how to input and output numbers in various bases within a program.


Number Representation

All numbers are stored in binary inside the computer, but different bases can be used in programs:

Base Radix NASM Notation Number Range (32-bit)
Binary 2 0b10101010 or 10101010b 0 and 1
Octal 8 0o52 or 52o 0-7
Decimal 10 42 0-9
Hexadecimal 16 0x2A or 2Ah 0-9, A-F

Relationship Between ASCII and Numbers

What is input and output on the screen are ASCII characters, not binary values.

Understanding the conversion between characters and values is the core of number processing in assembly:

Character ASCII Value Corresponding Value
'0' 0x30 (48) 0
'1' 0x31 (49) 1
'9' 0x39 (57) 9
'A' 0x41 (65) 10 (hexadecimal)
'F' 0x46 (70) 15 (hexadecimal)
'a' 0x61 (97) 10 (hexadecimal)

Character to number: value = ASCII code - '0' (i.e., ASCII code - 0x30)

Number to character: ASCII code = value + '0' (i.e., value + 0x30)


Inputting Numbers (String to Value)

What the user inputs is a sequence of characters, which needs to be converted to a binary value before it can be used in calculations:

Example

; File path: string_to_int.asm

; Convert a decimal digit string to an integer value

section .data
    input_str db '12345', 0  ; Input string "12345"
    input_len dd 5           ; String length

section .bss
    result_val resd 1        ; Store converted value

section .text
    global _start

_start:
    ; Conversion algorithm: result = 0
    ; result = result * 10 + (current character - '0')

    mov esi, input_str       ; esi points to input string
    mov ecx,      ; ecx = loop count
    mov eax, 0               ; eax = accumulated result

convert_loop:
    mov ebx, 10
    mul ebx                  ; eax = eax * 10
    ; mul ebx: edx:eax = eax * ebx

    mov bl,             ; Read current character
    sub bl, '0'              ; Convert to value: character - '0'
    movzx ebx, bl            ; Zero-extend ebx (bl -> ebx)
    add eax, ebx             ; eax = eax + current digit value

    inc esi                  ; Move to next character
    loop convert_loop

    ; eax now = 12345
    mov , eax    ; Save result

    mov eax, 1
    mov ebx, 0
    int 0x80

Algorithm analysis: Using "12345" as an example:

Round 1: result = 0Γ—10 + 1 = 1

Round 2: result = 1Γ—10 + 2 = 12

Round 3: result = 12Γ—10 + 3 = 123

...Finally obtaining 12345.


Outputting Numbers (Value to String)

Converting a binary value to a displayable decimal string:

Example

; File path: int_to_string.asm

; Convert an integer value to a decimal string and output it

section .data
    number dd 12345          ; Number to output
    newline db 0xA

section .bss
    output_buf resb 12       ; Output buffer (max 32-bit integer is 10 digits + sign + null)

section .text
    global _start

_start:
    mov eax,         ; Load number
    mov edi, output_buf + 11 ; edi points to end of buffer
    mov byte , 0        ; Null terminator (for debugging)
    dec edi

    mov ebx, 10              ; Divisor = 10
    mov ecx, 0               ; Digit counter

convert_digit:
    mov edx, 0               ; Clear edx (div requires edx:eax)
    div ebx                  ; eax = eax/10, edx = eax%10

    add dl, '0'              ; Convert remainder to character
    mov , dl            ; Store in buffer (from back to front)
    dec edi                  ; Buffer pointer moves forward
    inc ecx                  ; Digit count +1

    cmp eax, 0               ; Is quotient 0?
    jne convert_digit        ; No, continue loop

    ; Now edi+1 points to first valid digit character
    inc edi                  ; Fix pointer to point to string start

    ; Calculate valid character length
    ; output_buf + 11 - edi is the valid length

    ; Output number
    mov eax, 4
    mov ebx, 1
    mov ecx, edi             ; Point to converted string

    ; Calculate length
    mov edx, output_buf + 11
    sub edx, edi             ; edx = buffer end - string start

    int 0x80

    ; Output newline
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80

    mov eax, 1
    mov ebx, 0
    int 0x80

Running result:

$ nasm -f elf32 int_to_string.asm -o int_to_string.o
$ ld -m elf_i386 int_to_string.o -o int_to_string
$ ./int_to_string
12345

Hexadecimal Input and Output

Handling hexadecimal requires converting both 0-9 and A-F/a-f:

Example

; File path: hex_output.asm

; Output a value in hexadecimal format

section .data
    number dd 0x1A2B3C4D   ; Value to output
    hex_prefix db '0x'
    hex_prefix_len equ $ - hex_prefix
    newline db 0xA

section .bss
    hex_buf resb 10          ; 8 hex digits + prefix + null

section .text
    global _start

_start:
    ; Output prefix "0x"
    mov eax, 4
    mov ebx, 1
    mov ecx, hex_prefix
    mov edx, hex_prefix_len
    int 0x80

    mov eax,         ; Value to convert
    mov edi, hex_buf + 8     ; End of buffer (8 hex digits)
    mov ecx, 8               ; Loop 8 times (32 bits = 8 hex digits)

hex_loop:
    mov edx, 0               ; Prepare for division
    mov ebx, 16              ; Divide by 16
    div ebx                  ; Now: eax divided by ebx
    ; Note: div ebx is actually edx:eax / ebx
    ; Remainder in edx (0-15), quotient in eax

    mov ebx, eax             ; Save quotient

    ; Convert remainder to hex character
    mov al, dl
    cmp al, 10
    jl digit_09              ; 0-9
    add al, 'A'-10           ; A-F
    jmp store_char

digit_09:
    add al, '0'              ; 0-9

store_char:
    dec edi
    mov , al
    mov eax, ebx             ; Restore quotient
    loop hex_loop

    ; Removed loop, using direct decrement instead

    ; Output hex digits (8 digits)
    mov eax, 4
    mov ebx, 1
    mov ecx, hex_buf
    mov edx, 8
    int 0x80

    ; Output newline
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80

    mov eax, 1
    mov ebx, 0
    int 0x80

Complete Example: Simple Addition Calculator

Input two single-digit numbers from the keyboard, calculate their sum, and output the result:

Example

; File path: simple_calc.asm

; Input two single-digit numbers (0-9), calculate sum and output

section .data
    prompt1 db 'Enter first number (0-9): '
    prompt1_len equ $ - prompt1
    prompt2 db 'Enter second number (0-9): '
    prompt2_len equ $ - prompt2
    result_msg db 'Sum = '
    result_msg_len equ $ - result_msg
    newline db 0xA

section .bss
    num1 resb 2              ; First number input (1 digit + newline)
    num2 resb 2              ; Second number input
    result_str resb 3        ; Result string (max 2 digits + newline)

section .text
    global _start

_start:
    ; Prompt for first number
    mov eax, 4
    mov ebx, 1
    mov ecx, prompt1
    mov edx, prompt1_len
    int 0x80

    ; Read first number
    mov eax, 3
    mov ebx, 0
    mov ecx, num1
    mov edx, 2
    int 0x80

    ; Prompt for second number
    mov eax, 4
    mov ebx, 1
    mov ecx, prompt2
    mov edx, prompt2_len
    int 0x80

    ; Read second number
    mov eax, 3
    mov ebx, 0
    mov ecx, num2
    mov edx, 2
    int 0x80

    ; Calculate sum
    mov al,            ; Read first number (ASCII character)
    sub al, '0'              ; Convert to value
    mov bl,            ; Read second number
    sub bl, '0'              ; Convert to value
    add al, bl               ; Calculate sum

    ; Convert result to string
    mov ah, 0                ; Prepare for division
    mov bl, 10               ; Divide by 10
    div bl                   ; al = tens digit, ah = ones digit

    ; Save result
    add al, '0'              ; Tens digit to character
    mov , al     ; Store tens digit
    add ah, '0'              ; Ones digit to character
    mov [result_str+1], ah   ; Store ones digit
    mov byte [result_str+2], 0xA  ; Newline

    ; Output result message
    mov eax, 4
    mov ebx, 1
    mov ecx, result_msg
    mov edx, result_msg_len
    int 0x80

    ; Output calculation result (may be 1 or 2 digits)
    mov eax, 4
    mov ebx, 1
    mov ecx, result_str

    cmp byte , '0'
    je output_one_digit      ; If tens digit is '0', only output ones digit

    mov edx, 3               ; 2 digits + newline
    jmp do_output

output_one_digit:
    inc ecx                  ; Skip tens digit '0'
    mov edx, 2               ; 1 digit + newline

do_output:
    int 0x80

    mov eax, 1
    mov ebx, 0
    int 0x80

Running result:

$ nasm -f elf32 simple_calc.asm -o simple_calc.o
$ ld -m elf_i386 simple_calc.o -o simple_calc
$ ./simple_calc
Enter first number (0-9): 7
Enter second number (0-9): 8
Sum = 15

Handling number input and output in assembly requires a clear understanding of ASCII encoding and base conversion. Number to string (int to string) and string to number (string to int) are the two most fundamental utility functions. It is recommended to write and save them as templates for direct reuse later.

← Assembly ArrayAssembly Condition β†’