; Define a macro to write to stdout
%macro write 2
mov rax, 1 ; System call number for write
mov rdi, 1 ; File descriptor for stdout
mov rsi, %1 ; Address of the string to print
mov rdx, %2 ; Length of the string
syscall ; Invoke syscall to print
%endmacro
; Define a macro to read from stdin
%macro read 2
mov rax, 0 ; System call number for read
mov rdi, 0 ; File descriptor for stdin
mov rsi, %1 ; Address where input will be stored
mov rdx, %2 ; Maximum number of bytes to read
syscall ; Invoke syscall to read
%endmacro
section .data
msg1 db "Number : ", 0 ; Prompt for number input
msg1len equ $-msg1 ; Length of the prompt
endl db 10 ; Newline character
pcount db 0 ; Counter for positive numbers
ncount db 0 ; Counter for negative numbers
section .bss
hexnum resq 5 ; Array to store hexadecimal numbers
num1 resb 17 ; Temporary storage for input number
temp resb 16 ; Temporary storage for ASCII conversion
section .text
global _start
_start:
mov rcx, 5 ; Loop counter for 5 numbers
mov rsi, hexnum ; Pointer to hexnum array
nextnum:
push rcx ; Save loop counter
push rsi ; Save array pointer
read num1, 17 ; Read input number
call ascii_hex ; Convert ASCII input to hexadecimal
pop rsi ; Restore array pointer
pop rcx ; Restore loop counter
mov [rsi], rbx ; Store hexadecimal number in array
add rsi, 8 ; Move to next element in array
bt rbx, 63 ; Check the msb (if the number is negative)
jnc pcnt ; If not negative, increment positive count
inc byte[ncount] ; Increment negative count
jmp cont ; Continue to next number
pcnt: ; Label to increment positive count
inc byte[pcount] ; Increment positive count
cont: ; Label to continue to next number
loop nextnum ; Loop for next number
; for display number in hexdeimal form
mov rsi, hexnum ; Reset array pointer
mov rcx, 5 ; Reset loop counter
next2:
push rcx ; Save loop counter
push rsi ; Save array pointer
mov rbx, [rsi] ; Load number from array
call display ; Display the number
pop rsi ; Restore array pointer
pop rcx ; Restore loop counter
add rsi, 8 ; Move to next element in array
loop next2 ; Loop for next number
write endl, 1 ; Print newline
; for display nnumber of positive number
mov bl, [pcount] ; Load positive count into bl
call display8 ; Display positive count
write endl, 1 ; Print newline
; for display nnumber of negative number
mov bl, [ncount] ; Load negative count into bl
call display8 ; Display negative count
mov rax, 60 ; Exit syscall number
mov rsi, 0 ; Exit code
syscall
; Procedure to convert ASCII input to hexadecimal
ascii_hex:
mov rbx, 0 ; Clear rbx (hexadecimal result)
mov rsi, num1 ; Pointer to ASCII input
mov rcx, 16 ; Loop 16 times (for each digit)
next:
rol rbx, 4 ; Rotate left by 4 bits (1 nibble)
mov al, [rsi] ; Load ASCII character
cmp al, '9' ; Check if it's less than or equal to '9'
jbe sub30h ; If yes, jump to subtraction
sub al, 7h ; Otherwise, subtract 7 to convert from 'A' to 'F'
sub30h: ; Label to subtract '0'
sub al, 30h ; Subtract '0' to get hexadecimal value
add bl, al ; Add to result in rbx
inc rsi ; Move to next character
loop next ; Repeat for each digit
ret ; Return
; Procedure to display hexadecimal number
display:
mov rsi, temp ; Pointer to temporary storage
mov rcx, 16 ; Loop 16 times (for each digit)
next1:
rol rbx, 4 ; Rotate left by 4 bits (1 nibble)
mov al, bl ; Load current nibble
and al, 0Fh ; Mask upper bits to get only lower 4 bits
cmp al, 9 ; Check if it's greater than 9
jbe add30h ; If not, jump to addition
add al, 7h ; Otherwise, add 7 to convert from 10-15 to 'A' to 'F'
add30h: ; Label to add '0'
add al, 30h ; Add '0' to get ASCII value
mov [rsi], al ; Store in temporary storage
inc rsi ; Move to next character
loop next1 ; Repeat for each digit
write temp, 16 ; Display the hexadecimal number
write endl, 1 ; Print newline
ret ; Return
; Procedure to display a single byte (8 bits)
display8:
mov rsi, temp ; Pointer to temporary storage
mov rcx, 2 ; Loop 2 times (for 2 hexadecimal digits)
next18:
rol bl, 4 ; Rotate left by 4 bits (1 nibble)
mov al, bl ; Load current nibble
and al, 0Fh ; Mask upper bits to get only lower 4 bits
cmp al, 9 ; Check if it's greater than 9
jbe add30h8 ; If not, jump to addition
add al, 7h ; Otherwise, add 7 to convert from 10-15 to 'A' to 'F'
add30h8: ; Label to add '0'
add al, 30h ; Add '0' to get ASCII value
mov [rsi], al ; Store in temporary storage
inc rsi ; Move to next character
loop next18 ; Repeat for each digit
write temp, 2 ; Display the hexadecimal number
write endl, 1 ; Print newline
ret ; Return Write, Run & Share Assembly code online using OneCompiler's Assembly online compiler for free. It's one of the robust, feature-rich online compilers for Assembly language. Getting started with the OneCompiler's Assembly compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as Assembly and start coding.
Assembly language(asm) is a low-level programming language, where the language instructions will be more similar to machine code instructions.
Every assembler may have it's own assembly language designed for a specific computers or an operating system.
Assembly language requires less execution time and memory. It is more helful for direct hardware manipulation, real-time critical applications. It is used in device drivers, low-level embedded systems etc.
Assembly language usually consists of three sections,
Data section
To initialize variables and constants, buffer size these values doesn't change at runtime.
bss section
To declare variables
text section
_start specifies the starting of this section where the actually code is written.
There are various define directives to allocate space for variables for both initialized and uninitialized data.
variable-name define-directive initial-value
| Define Directive | Description | Allocated Space |
|---|---|---|
| DB | Define Byte | 1 byte |
| DW | Define Word | 2 bytes |
| DD | Define Doubleword | 4 bytes |
| DQ | Define Quadword | 8 bytes |
| DT | Define Ten Bytes | 10 bytes |
| Define Directive | Description |
|---|---|
| RESB | Reserve a Byte |
| RESW | Reserve a Word |
| RESD | Reserve a Doubleword |
| RESQ | Reserve a Quadword |
| REST | Reserve a Ten Bytes |
Constants can be defined using
CONSTANT_NAME EQU regular-exp or value
%assign constant_name value
%define constant_name value
Loops are used to iterate a set of statements for a specific number of times.
mov ECX,n
L1:
;<loop body>
loop L1
where n specifies the no of times loops should iterate.
Procedure is a sub-routine which contains set of statements. Usually procedures are written when multiple calls are required to same set of statements which increases re-usuability and modularity.
procedure_name:
;procedure body
ret