NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: razor3x on August 07, 2018, 11:11:18 PM
-
I'm trying to make a simple HEX editor, but it prints only first 3376 bytes and throws segfault exception. However, in GDB it works correctly and prints the whole file!
section .bss
stat resq 18
buf resq 6
raw resb 0
section .data
no_args db 'No arguments', 10
desc dq 0
section .text
global _start
_start:
pop r14 ; argc
cmp r14, 2
jl _no_args
pop rdi ; first arg is the program name
; get the file size
mov rax, 4 ; SYS_NEWSTAT
pop rdi
push rdi
mov rsi, stat
syscall
mov r14, qword [stat + 48]
; allocate the memory in heap
mov rax, 12 ; SYS_BRK
xor rdi, rdi
syscall
lea rdi, [rax + r14]
mov rax, 12
syscall
; get all bytes from file
mov rax, 2 ; SYS_OPEN
pop rdi
mov rsi, 666q
syscall
mov [desc], rax
xor rax, rax
mov rdi, [desc]
mov rsi, raw
mov rdx, r14
syscall
mov rax, 3 ; SYS_CLOSE
mov rdi, [desc]
syscall
; prepare main registers to SYS_WRITE calls
;
; 1 syscall = 1 string = 16 bytes separated by space and line feed at end
; r12 - current line index, r13 - global index, r14 - byte count
mov rdi, 1
mov rsi, buf
mov rdx, 48
; first space position
mov r12, 2
_space:
mov byte [rsi + r12], ' '
add r12, 3
cmp r12, 47
jl _space
; add line break
mov byte [rsi + r12], 10
_print:
call _line
cmp r13, r14
jl _print
jmp _exit
_no_args:
mov rax, 1
mov rdi, 1
mov rsi, no_args
mov rdx, 13
syscall
_exit:
mov rax, 60
xor rdi, rdi
syscall
_line:
xor r12, r12
_byte:
mov bl, byte [raw + r13]
shr bl, 4
call _nibble
inc r12
mov bl, byte [raw + r13]
and bl, 15
call _nibble
inc r13
cmp r13, r14
je _break
add r12, 2
cmp r12, 47
jl _byte
jmp _write
_break:
inc r12
mov byte [rsi + r12], 10
mov rdx, r12
inc rdx
_write:
mov rax, 1 ; SYS_WRITE
syscall
ret
_nibble:
cmp rbx, 10
jl _less
add rbx, 7
_less:
add rbx, 48
mov byte [rsi + r12], bl
ret
-
Hi razor3x,
Welcome to the Forum.
I do not see the problem with your program. I'll look more.
I think I see an issue with the parameters to sys_open. 666q looks like a mode to me. Should be in rdx? Ignored? In rsi should be flags - O_RDONLY - 0 - probably? This is not the problem and doesn't seem to make any difference, but I thought I'd mention it...
Nice work! Good luck finding the problem. I'll look more but don't count on me!
Best,
Frank
-
The 3376 bytes before the segfault might be the remainder of the 4096 the .bss probably allocates before the sys_brk's. I increased raw to resb 100000 - big enough for my test file. No segfault! So... looks like something in your allocation isn't working? Dunno why or why it works in GDB... Thought I'd pass that along. Maybe more later...
Best,
Frank
-
Nevermind, i just forgot to free the memory and access the buffer by value (not by address!). Thank you so much, you saved my time :)
; print the whole file
section .bss
stat resq 18
brk resb 0
section .data
no_args db 'No arguments', 10
desc dq 0
section .text
global _start
_start:
pop r14 ; argc
cmp r14, 2
jl _no_args
pop rdi
mov rax, 4 ; SYS_NEWSTAT
pop rdi
push rdi
mov rsi, stat
syscall
mov r14, qword [stat + 48]
mov rax, 12 ; SYS_BRK
xor rdi, rdi
syscall
mov [brk], rax
push rcx ; caller-saved register
mov rcx, r14
lea rdi, [rcx + rax]
mov rax, 12
syscall
pop rcx
mov rax, 2 ; SYS_OPEN
pop rdi
xor rsi, rsi
syscall
mov [desc], rax
xor rax, rax
mov rdi, [desc]
mov rsi, [brk]
mov rdx, r14
syscall
mov rax, 3 ; SYS_CLOSE
mov rdi, [desc]
syscall
mov rax, 1
mov rdi, 1
syscall
mov rax, 12
mov rdi, r14
syscall
jmp _exit
_no_args:
mov rax, 1
mov rdi, 1
mov rsi, no_args
mov rdx, 13
syscall
_exit:
mov rax, 60
xor rdi, rdi
syscall