Re: Completely confused. Please send help. :)



Thank you both for the suggestions/explainations/pointers on the code. I was backward in my thinking on which was the start of my buffer. I was figuring the top-most part was the start.

I now have the code working (I think) :) I ended up doing some different things to get the numbers to not be backwards. itoa() has its own buffer to accomplish this and then I copy the result into the buffer* passed in via a simple "rep movsb".

If it's not too much to ask, could someone look at this version to see if I finally "get it" :) Thanks!


------------- DRIVER CODE -------------------------

section .data
msg: db 'Hello, world',10
msglen: equ $-msg

%define stdout 1

%define SYSCODE_exit 1
%define SYSCODE_write 4

%define EXIT_SUCCESS 0
%define EXIT_FAILURE 1


%macro SYS_write 1-3
mov ebx, %1

%if %0 > 2
mov ecx, %2
mov edx, %3
%endif

mov eax, SYSCODE_write
int 80h
%endmacro


section .text
global _start
extern itoa

_start:
SYS_write stdout, msg, msglen

cmp eax, 0
jge .GOOD

; This indicates we received an error (negative number)
mov ebx, EXIT_FAILURE
jmp .RET


.GOOD:
%define buffer_size 16

; Allocate buffer space
sub esp, buffer_size
mov ebx, esp

; Size of buffer space we allocated
; This is changed by itoa() to be the
; size of the buffer
push dword buffer_size

; Address of buffer we allocated
push ebx

; Number we want to convert
push eax

call itoa

pop eax

; Data we want to write
pop ecx

; Length of data we want to write
pop edx

; Get rid of itoa parameters
add esp, buffer_size

; Write to terminal
SYS_write stdout

; Exit code
mov ebx, EXIT_SUCCESS

.RET:
mov eax, SYSCODE_exit
int 80h

------------- END DRIVER -------------------


-------- ITOA ------------------

section .text
global itoa

itoa:
push ebp
mov ebp, esp

;; parameters on stack (number, buffer*, buffer_size)
%define number [ebp+8]
%define buf_addr [ebp+12]
%define buf_size [ebp+16]

push ebx
push edx
push esi

; Make room for local buffer
%define l_buffer_size 16
sub esp, l_buffer_size
lea esi, [esp+l_buffer_size]


; Number to stringify
mov eax, number

; Do we have a positive number?
cmp eax, 0
jge .ASSIGN

; If not, make it so
neg eax

.ASSIGN:
; Set up divisor
mov ecx, 10

; Counter for length to make sure we don't
; go past buffer_size bytes
mov ebx, 0

%macro CHECK_BUFFER_SIZE 0
; Check to make sure we don't overflow
; the size of buffer
cmp ebx, buf_size
je .RET
%endmacro

..DO.WHILE:
mov edx, 0

; [eax] is always being changed to what we
; need so no need to reassign it here
div ecx

add edx, 48

; Add next number to the sequence
dec esi
mov [esi], dl
inc ebx

CHECK_BUFFER_SIZE

; Do we need to loop?
cmp eax, 0
jnz .DO.WHILE

cmp dword number, 0
jge .RET

; Add the sign for negative numbers
dec esi
mov byte [esi], '-'
inc ebx

..RET:
; Modify the buffer size parameter to be the
; number of bytes we wrote to buffer
mov buf_size, ebx

; Copy esi -> edi
push edi
mov edi, buf_addr
mov ecx, ebx
cld
rep movsb
pop edi

; Restore stack and kill local variables
add esp, l_buffer_size
pop esi
pop edx
pop ebx
mov esp, ebp
pop ebp
ret

------ END ITOA --------------

.



Relevant Pages