You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

160 lines
3.0 KiB

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Converts integer to string
; IN: eax = number to convert
; IN: edi = base of string buffer
; OUT: ecx = number of characters written to buffer
IntToString:
push eax
push esi
push edx
push edi
push ebp
mov ecx, esi ; store negative original buffer base
neg ecx ; (used for counting amount of characters)
test eax, eax
jns .not_negative
mov BYTE [esi], '-'
neg eax
add esi, 1
.not_negative:
mov edi, esi ; store pointer after potential negative sign character
mov ebp, 0xcccccccd ; ebp = 32 bit multiplicative reciprocal of 10
.divide_loop:
mov ebx, eax ; save number in ebx
mul ebp
shr edx, 3 ; edx = quotient
lea eax, [edx + edx*4] ; eax = quotient * 10 = (number - remainder)
add eax, eax ; |
sub ebx, eax ; ebx = number - (number - remainder) = remainder
add ebx, '0' ; remainder is our digit, turn it ASCII
mov BYTE [esi], bl ; store ASCII digit to buffer
lea esi, [esi+1]
mov eax, edx ; We need quotient in eax for 'mul'
test eax, eax
jne .divide_loop
add ecx, esi ; Update amount of characters
mov byte [esi], 0x00 ; Add null terminator to end of string
lea esi, [esi-1] ; We incremented the buffer pointer once too much
.swap_loop:
cmp edi, esi
jae .done_swapping
movzx eax, BYTE [esi]
movzx edx, BYTE [edi]
mov BYTE [esi], dl
mov BYTE [edi], al
sub esi, 1
add edi, 1
jmp .swap_loop
.done_swapping:
pop ebp
pop edi
pop edx
pop esi
pop eax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Right justifies source string within the given justification width
; IN: esi = base of string buffer
; IN: edx = justification width
; IN: ecx = string length
; IN: al = padding char
; ASSUMES: that the justification width > string length
; ASSUMES: that the size of the string buffer > justification width
RightJustifyString:
pushad
pushfd
lea edi, [esi + edx-1]
lea esi, [esi + ecx-1]
sub edx, ecx
std ; Move string from the end
rep movsb ; |
mov ecx, edx
rep stosb ; Pad with AL
popfd
popad
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Copies ecx bytes
; IN: esi = source
; IN: edi = destination
; IN: ecx = number of bytes to copy
CopyData:
pushad
mov edx, ecx
and edx, 11b
shr ecx, 2
; ecx = quotient, edx = remainder
rep movsd
mov ecx, edx
rep movsb
popad
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Puts the stringified version of eax on the stack
; IN: esi = base of string
; IN: ecx = string length
; IN: ah = character attributes
PrintString:
push ecx
push eax
push edi
push esi
.print_loop:
mov al, byte [esi]
mov word [edi], ax
lea esi, [esi+1]
lea edi, [edi+2]
sub ecx, 1
jnz .print_loop
pop esi
pop edi
pop eax
pop ecx
ret