Welcome.
I have following code:
%define ESC 0x1b
section .text
global _start
_start:
.drawer:
call getdata
mov rdi, 1
call sleep
jmp .drawer
mov rdi, 0
mov rax, 60 ;; sys_exit
syscall ;; exit
sleep:
mov [timespec.tv_sec], rdi
xor rdi, rdi
mov [timespec.tv_usec], rdi
mov rdi, timespec
xor rsi, rsi
mov rax, 35 ;; sys_nanosleep
syscall ;; nanosleep
ret
getuptime:
mov rdx, 16
mov rsi, data.uptimebuf
mov rdi, filename.uptime
call readfile
mov rdi, rsi
mov rsi, 0x2e ;; ASCII '.'
call strclen
mov rsi, rax
call stoin
mov qword [data.uptime], rax
mov rdi, qword [data.uptime]
call printi
ret
getdata:
call getuptime
ret
section .data
data:
.uptime dq 0
.uptimebuf times 16 db 0
timespec:
.tv_sec dq 0
.tv_usec dq 0
section .rodata
ansi:
.clear db ESC, "[2J", ESC, "[H"
.clearlen equ $ - .clear
filename:
.uptime db "/proc/uptime"
;; Content under this line is included on beginning like this:
;; %include "libasm.asm"
;; under line
;; %define ESC 0x1b
section .text
strlen: ;; string: rdi
push rbx
mov rbx, rdi
.again:
cmp byte [rbx], 0
jz .done
inc rbx
jmp .again
.done:
sub rbx, rdi
mov rax, rbx
pop rbx
ret
strclen: ;; string: rdi, char: rsi
push rbx
mov rbx, rsi
mov al, bl
mov rbx, rdi
.again:
cmp byte [rbx], 0
jz .done
cmp byte [rbx], al
je .done
inc rbx
jmp .again
.done:
sub rbx, rdi
mov rax, rbx
pop rbx
ret
printn: ;; string: rdi, len: rsi
push rdx
push rsi
push rdi
mov rdx, rsi
mov rsi, rdi
mov rdi, 1
mov rax, 1 ;; sys_write
syscall ;; write(unsigned int fd, const char *buf, size_t count)
pop rdi
pop rsi
pop rdx
ret
stoin: ;; string: rdi, len: rsi
push rdx
push rcx
push rbx
mov rdx, rdi
xor rcx, rcx
xor rax, rax
.again:
mov rbx, 10
cmp rcx, rsi
jge .done
push rdx
mul rbx
pop rdx
xor rbx, rbx
mov bl, byte [rdx]
sub bl, 0x30 ;; ASCII '0'
add rax, rbx
inc rdx
inc rcx
jmp .again
.done:
pop rbx
pop rcx
pop rdx
ret
readfile: ;; filename: rdi, buffer: rsi, length: rdx
push rsi
xor rsi, rsi
mov rax, 2 ;; sys_open
syscall ;; open(char *filename, int flags, int mode)
pop rsi
push rdi
mov rdi, rax
mov rax, 0 ;; sys_read
syscall ;; read(unsigned int fd, const char *buf, size_t count)
mov rax, 3 ;; sys_close
syscall ;; close(unsigned int fd);
pop rdi
ret
printi: ;; long: rdi
extern printf
section .data
fmt db "%ld", 10, 0
section .text
push rsi
mov rsi, rdi
mov rdi, fmt
call printf
pop rsi
ret
If it stays like that, everyething works properly, but I want to move last 2 instructions before ret
in getuptime
function to place just after calling getuptime
, just like that:
getuptime:
mov rdx, 16
mov rsi, data.uptimebuf
mov rdi, filename.uptime
call readfile
mov rdi, rsi
mov rsi, 0x2e ;; ASCII '.'
call strclen
mov rsi, rax
call stoin
mov qword [data.uptime], rax
ret
getdata:
call getuptime
mov rdi, qword [data.uptime]
call printi
ret
but when I'll do it, i am getting Segmentation Fault or Bus Error. Why?