Hello everyone.. I was doing some exercise with hexdump and Im trying to convert the hexdump program from 32 bit into 64 bit, The problem is what i dont get the same output as hexdump 32 bit. Could someone please help me to find where exactly the problem is ? Thanks.
;----------------------------;
; ./hexdump1 < (input file) ;
;----------------------------;
SECTION .data ; section containing initialised data
HexStr db " 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",10
HexLen equ $-HexStr
Digits db "0123456789ABCDEF"
SECTION .bss ; section containing uninitialised data
BUFFLEN EQU 16 ; We read the file 16 bytes at a time
Buff resb BUFFLEN ; Text buffer itself
SECTION .text ; section containing code
global _start ; Linker needs this to find the entry point!
_start:
nop ; This no-op keeps gdb happy
Read:
mov eax, 3 ; specify sys_read call
mov ebx, 0 ; specify File Descriptor 0: Standard Input
mov ecx, Buff ; Pass offset of the buffer to read to
mov edx, BUFFLEN ; Pass number of bytes to read at one pass
int 80h ; Call sys_read to fill the buffer
mov ebp, eax ; Save # of bytes read from file for later
cmp eax, 0 ; If eax=0, sys_read reached EOF on stdin
je Done ; Jump if equal (to 0, from compare)
; Set up the registers for the process buffer step:
mov esi, Buff ; Place address of file buffer into esi
mov edi, HexStr ; Place address of line string into edi
xor ecx, ecx ; Clear line string pointer to 0
; Go through the buffer and convert binary values to hex digits:
Scan:
xor eax, eax ; Clear eax to 0
; Here we calculate the offset into the line string, which is ecx x 3
mov edx, ecx ; Copy the pointer into line string into edx
shl edx, 1 ; Multiply pointer by 2 using shift left
add edx, ecx ; Complete the multiplication X3
lea edx, [edx*2+edx]
; Get a character from the buffer and put it in both eax and ebx
mov al, byte [esi+ecx] ; Put a byte from the input buffer into al
mov ebx, eax ; Duplicate the byte in bl for second nybble
; Look up low nybble character and insert it into the string:
and al, 0Fh
mov al, byte [Digits+eax] ; Look up the char equivalent of nybble
mov byte [HexStr+edx+2], al ; Write the char equivalent to line string
; Look up high nybble character and insert it into the string:
shr bl, 4 ; Shift high 4 bits of char into low 4 bits
mov bl, byte [Digits+ebx] ; Look up char equivalent of nybble
mov byte [HexStr+edx+1], bl ; Write the char equivalent to line string
; Bump the buffer pointer to the next character and see if we are done:
inc ecx ; Increment line string pointer
cmp ecx, ebp ; Compare to the number of characters in the buffer
jna Scan ; Loop back if ecx is <= number of chars in buffer
; Write the line of hexadecimal values to stdout:
mov eax, 4 ; Specify sys_Write call
mov ebx, 1 ; Specify File Descriptor 1: Standard output
mov ecx, HexStr ; Pass offset of line string
mov edx, HexLen ; Pass size of the line string
int 80h ; make kernell call to display line string
jmp Read ; Loop back and load file buffer again
; All done! Let's end this party:
Done:
mov eax, 1 ; Code for Exit Syscall
mov ebx, 0 ; Return a code of zero
int 80h ; Make kernel call
;-------------------------------;
; ./hexdump1-64 < inputFile ;
;-------------------------------;
SECTION .data ; section containing initialised data
HexStr db " 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",10
HexLen equ $-HexStr
Digits db "0123456789ABCDEF"
SECTION .bss ; section containing uninitialised data
BUFFLEN EQU 16 ; We read the file 16 bytes at a time
Buff resb BUFFLEN ; Text buffer itself
SECTION .text ; section containing code
global _start ; Linker needs this to find the entry point!
_start:
nop ; This no-op keeps gdb happy
Read:
mov rax, 0 ; specify sys_read call
mov rdi, 0 ; specify File Descriptor 0: Standard Input
mov rsi, Buff ; Pass offset of the buffer to read to
mov rdx, BUFFLEN ; Pass number of bytes to read at one pass
syscall ; Call sys_read to fill the buffer
mov rbp, rax ; Save # of bytes read from file for later
cmp rax, 0 ; If eax=0, sys_read reached EOF on stdin
je Done ; Jump if equal (to 0, from compare)
; Set up the registers for the process buffer step:
mov rbx, Buff ; Place address of file buffer into esi
mov rcx, HexStr ; Place address of line string into edi
xor rsi, rsi ; Clear line string pointer to 0
; Go through the buffer and convert binary values to hex digits:
Scan:
xor rax, rax ; Clear eax to 0
; Here we calculate the offset into the line string, which is ecx x 3
mov rdx, rsi ; Copy the pointer into line string into edx
shl rdx, 1 ; Multiply pointer by 2 using shift left
add rdx, rsi ; Complete the multiplication X3
lea rdx, [rdx*2+rdx] ;
; Get a character from the buffer and put it in both eax and ebx
mov al, byte [rbx+rsi] ; Put a byte from the input buffer into al ; al
mov rdi, rax ; Duplicate the byte in bl for second nybble
; Look up low nybble character and insert it into the string:
and al, 0Fh
mov al, byte [Digits+rax] ; Look up the char equivalent of nybble
mov byte [HexStr+rdx+2], al ; Write the char equivalent to line string
; Look up high nybble character and insert it into the string:
shr dl, 4 ; Shift high 4 bits of char into low 4 bits
mov dl, byte [Digits+rdi] ; Look up char equivalent of nybble
mov byte [HexStr+rdx+1], dl ; Write the char equivalent to line string
; Bump the buffer pointer to the next character and see if we are done:
inc rsi ; Increment line string pointer
cmp rsi, rbp ; Compare to the number of characters in the buffer
jna Scan ; Loop back if ecx is <= number of chars in buffer
; Write the line of hexadecimal values to stdout:
mov rax, 1 ; Specify sys_Write call
mov rdi, 1 ; Specify File Descriptor 1: Standard output
mov rsi, HexStr ; Pass offset of line string
mov rdx, HexLen ; Pass size of the line string
syscall ; make kernell call to display line string
jmp Read ; Loop back and load file buffer again
; All done! Let's end this party:
Done:
mov rax, 60 ; Code for Exit Syscall
mov rdi, 0 ; Return a code of zero
syscall ; Make kernel call