I could not get c function calls to work inside of nasm so i wrote my own read integer procedure. Im sure its inefficient and could be greatly imporved but right now I'm interested in where the negative sign went. Any help is greatly apreiciated.
;---------------------------------------------------------;
;reads a 64 bit integer from the consol and returns in rax;
;---------------------------------------------------------;
read_int:
push rbx ;these registers are nonvolitile and must be saved
push rdi
push rsi
mov rsi, sint ;load string address
mov rdi, rsi ;duplicat address
add rdi, 21 ;shift to end of string
.purge: ;sets all string contents to null
mov byte[rsi], 0;set byte to 0
inc rsi ;move to next byte
cmp rsi, rdi ;check if at end of string
je .end_purge ;exit loop if at end
jmp .purge ;loop
.end_purge:
mov rax, 3 ;system call code for read_string
mov rbx, 0 ;where to read from. in this case std_in
mov rcx, sint ;where the place the resultant string
mov rdx, 21 ;how many characters to read
int 0x80 ;system call
mov rcx, 0 ;set registers rax, rbx, and rcx to 0
mov rax, 0
mov rbx, 0
mov rsi, sint ;load address of string into rsi and rdi
mov rdi, sint
add rdi, 21 ;shift rdi to the end of the string
mov bl, byte[rsi] ;load the first character in the string
cmp rbx, 43 ;if charachter is + sign continue
je .convert
cmp rbx, 45 ;if character is - sign continue
je .convert
sub rbx, 48 ;shift character to its literal value
cmp rbx, 0 ;test if it is a number greator than 0
jl .endr1 ;if not exit procedure
cmp rbx, 9 ;test if it is a number less than 9
jg .endr1 ;if not exit procedure
add rax, rbx ;if it is a valid number add it to the result.
dec rdi ;if first char is an integer we can only read 18 more
;so we need to shif rdi closer to start of string
;this way it will exit once we have read 19 total numbers
;does the actual conversion from string to number
.convert:
inc rsi ;increment rsi to point to next byte
cmp rsi, rdi ;check if we are at the end of the string
je .endr1
mov bl, byte[rsi] ;load next byte
sub rbx, 48
cmp rbx, 0 ;if this is not a valid number end procedure
jl .endr1
cmp rbx, 9
jg .endr1
mov rdx, 10
mul rdx ;multiply rax by 10 to make room for new ones place
add rax, rbx ;add the new number to the result
jmp .convert
.endr1:
mov bl, byte[sint] ;get first byte of integer string if minus do -result
cmp rbx, 45
jne .endr2
not rax ;convert rax to a negative
inc rax ;increment to get back to origional magnitude
.endr2:
pop rsi ;restore saved values
pop rdi
pop rbx
ret ;return to caller
;-----------------------------------------;
;prints the integer in rax to standard out;
;-----------------------------------------;
print_int:
push rbx ;save these registers as they are nonvolitile
push rdi
push rsi
mov rsi, sint ;load address to store string
mov r10, 10 ;load divisor
mov rcx, 0 ;clear registers
mov rdx, 0
mov rdi, rsi ;copy address
add rdi, 21 ;shift to end of space
.purge: ;make all bytes null same as above
mov byte[rsi], 0
inc rsi
cmp rsi, rdi
je .end_purge
jmp .purge
.end_purge:
mov rsi, sint ;restore origional values
mov rdi, 0
cmp rax, 0 ;compair the number to 0
jg .convert ;if its positive skip to convert
jl .neg ;if its negative skip to neg
mov byte[rsi], 48 ;if its 0 add literal 0 to string
jmp .endp1 ;jump to print
.neg:
not rax ;take negation to make positive
inc rax ;increment to restore magnitude
mov byte[rsi], 45 ;add the - sign to print string
inc rsi ;increment pointer
.convert:
cmp rax, 0 ;see if we are out of integers to convert
je .converts ;if so create string with chars
inc rcx ;increment counter
div r10 ;divide by 10 placeing remainder in rdx and quotient in rax
add rdx, 48 ;convert remainder to its char value
mov r8, rdx ;move to r8
push r8 ;push onto the stack
mov rdx, 0 ;set rdx to 0
jmp .convert ;loop
.converts:
cmp rcx, 0 ;see if we are out of characters to concat
je .endp1 ;if so go to print
dec rcx ;decrement counter
pop rbx ;pop a char
mov byte[rsi], bl ;concat char to string
inc rsi ;adjust string pointer to next empty slot
jmp .converts ;loop
.endp1:
mov rax, 4 ;system call code for print_string
mov rbx, 1 ;print to std_out
mov rcx, sint ;address of string to print
mov rdx, 20 ;number of chars to print
int 0x80 ;system call
pop rsi ;restore saved values
pop rdi
pop rbx
ret
I also included my print procedure to make it easier to test the read procedure should you decide to run it.
Thanks.