Write X86/64 ALP to count number of positive and negative numbers from the array.
%macro print 2 ;Macro for printing
mov rax, 1 ;rax = 1 for sys_write
mov rdi, 1 ;unsigned int file descriptor
mov rsi, %1 ;Buffer address
mov rdx, %2 ;Buffer length
syscall ;Makes system call
%endmacro
%macro input 2 ;Macro for reading
mov rax, 0 ;rax = 0 for sys_read
mov rdi, 0 ;unsigned int file descriptor
mov rsi, %1 ;Buffer address
mov rdx, %2 ;Buffer length
syscall ;Makes system call
%endmacro
section .data ;For declaring initialized data
mssg db "Write a X86/64 ALP to count number of positive and negative numbers from the array."
mssg_len:equ $ - mssg
mssg_name db "AMAN THAKUR 3205" ;Initialising mssg_name
mssg_name_len: equ $-mssg_name
mssg1 db "Enter your number : "
mssg1_len:equ $ - mssg1
mssg_pos_cnt db "Total positive numbers : "
mssg_pos_cnt_len:equ $ - mssg_pos_cnt
mssg_neg_cnt db "Total negative numbers : "
mssg_neg_cnt_len:equ $ - mssg_neg_cnt
cnt_positive db 0 ;To store count of +ve numbers
cnt_negative db 0 ;To store count of -ve numebrs
mssg_error db "Error!!"
mssg_error_len:equ $-mssg_error
space db " "
newline db 10
section .bss ;For declaring variables.
num1 resb 17 ;Reserving 17 Byte.
positive resq 5 ;Reserving 5 quad word for positive array.
negative resq 5 ;Reserving 5 quad word for negative array.
temp resb 16 ;To store 64 bit result to display
temp2 resb 2 ;To store 8 bit result to display
section .text ;Actual code is present.
global _start ;has to be declared for linker(ld).
_start: ;tells linker entry point.
print mssg, mssg_len ;Problem Statement.
print newline, 1
print mssg_name, mssg_name_len ;Name and roll number.
print newline, 1
mov rsi, positive ;Pointing to rsi to first index of positive
mov rdi, negative ;Pointing to rdi to first index of negative
mov rcx, 5
;=======Input and counting positive and negative numebers========
next0 :
push rcx
push rsi ;Pushing registers in stack to avoid change in values
push rdi
print mssg1, mssg1_len
input num1, 17
call ascii_hex64
pop rdi
pop rsi
bt rbx, 63 ;Copies the value of bit indexed into the carry flag
jc is_negative
mov [rsi], rbx ;In Case number is positive, storing it in positive arr
add rsi, 8 ;Making rsi point to next element
inc byte[cnt_positive]
jmp Continue
is_negative:
mov [rdi], rbx ;In Case number is negative, storing it in negative arr
add rdi, 8 ;Making rdi point to next element
inc byte[cnt_negative]
Continue:
pop rcx
dec rcx
jnz next0
print newline, 1
;=========== Displaying Positive Numbers ==========
print mssg_pos_cnt, mssg_pos_cnt_len
mov bl, [cnt_positive] ;Storing positive count in bl to display
call display8 ;To display positive count
print newline, 1
mov rcx, [cnt_positive]
mov rsi, positive ;Making rsi point to start of positive arr
next_pos:
mov rbx, [rsi] ;Storing value in rbx to display
push rsi
call display64
print newline, 1
pop rsi
add rsi, 8 ;Incrementing rsi to point next index
dec byte[cnt_positive]
jnz next_pos
print newline, 1
;==============Displaying Negative Numbers ==============
print mssg_neg_cnt, mssg_neg_cnt_len
mov bl, [cnt_negative] ;Storing negative count in bl to display
call display8 ;To display negative count
print newline, 1
mov rcx, [cnt_negative]
mov rdi, negative ;Making rdi point to start of negative arr
next_neg:
mov rbx, [rdi] ;Storing value in rbx to display
push rdi
call display64
print newline, 1
pop rdi
add rdi, 8 ;Incrementing rdi to point next index
dec byte[cnt_negative]
jnz next_neg
Exit:
mov rax, 60 ;rax = 60 for sys_exit.
mov rdi, 0
syscall
err:
print mssg_error, mssg_error_len ;Error mssg for invalid input.
print newline, 1
mov rax, 60
mov rdi, 0
syscall
ascii_hex64:
mov rcx, 16
mov rsi, num1 ;rsi points to num1
mov rbx, 0
next:
rol rbx, 4 ;Rotating by 4 bits to left, 0Fh -> F0h
mov al, [rsi] ;Assigning [rsi] to al
cmp al, 2Fh ;Checking For Error
jbe err ;Case: al < 30h (0)
cmp al, 47h
jge err ;Case: al > 46h (F)
cmp al, 39h
jle ELSE ;Case: al <= 39h (9), No Error
cmp al, 40h
jle err ;Case al > 39(9) and al < 41(A)
ELSE:
cmp al, 39h ;Here we convert ascii to hex
jbe sub30h ;If al <= 39h (9), subtract 30h
sub al, 7h ;Else subtract 37h
sub30h:
sub al, 30h ;Subtracting 30h from al
add bl, al
inc rsi
dec rcx
jnz next
ret ;Return
display64:
mov rcx, 16
mov rsi, temp ;rsi points to len
next1:
rol rbx, 4 ;rotating by 4 bits to left
mov al, bl
and al, 0Fh ;To get only last digit, eg. 5Ah & 0Fh = 0Ah
cmp al, 9h ;Case : al <= 9h (9)
jbe add30h ;If True add 30h
add al, 7h ;Else add 37h
add30h:
add al, 30h ;Adding 30h to al
mov [rsi], al ;Storing al in temp
inc rsi
dec rcx
jnz next1
print temp, 16 ;Printing number in ascii
ret ;Return
display8:
mov rcx, 2
mov rsi, temp2 ;rsi points to len
next2:
rol bl, 4 ;rotating by 4 bits to left
mov al, bl
and al, 0Fh ;To get only last digit, eg. 5Ah & 0Fh = 0Ah
cmp al, 9h ;Case : al <= 9h (9)
jbe add30h2 ;If True add 30h
add al, 7h ;Else add 37h
add30h2:
add al, 30h ;Adding 30h to al
mov [rsi], al ;Storing al in temp
inc rsi
dec rcx
jnz next2
print temp2, 2 ;Printing number in ascii
ret ;Return
0 Comments
If you have any doubt pls let me know..