6 changed files with 508 additions and 286 deletions
@ -0,0 +1,74 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||||
; Puts the stringified version of eax on the stack |
||||
; IN: eax = number to write |
||||
; IN: edi = base of where to write string |
||||
; OUT: ecx = number of characters written to buffer |
||||
IntToString: ; (eax = number, edi = buffer base) -> ecx = number of characters |
||||
push eax |
||||
push edi |
||||
;push ecx |
||||
push edx |
||||
push esi |
||||
push ebp |
||||
|
||||
mov ecx, edi ; store negative original buffer base |
||||
neg ecx ; (used for counting amount of characters) |
||||
|
||||
test eax, eax |
||||
jns .not_negative |
||||
|
||||
mov BYTE [edi], '-' |
||||
neg eax |
||||
add edi, 1 |
||||
|
||||
.not_negative: |
||||
mov esi, edi ; 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 [edi], bl ; store ASCII digit to buffer |
||||
lea edi, [edi+1] |
||||
|
||||
mov eax, edx ; We need quotient in eax for 'mul' |
||||
|
||||
test eax, eax |
||||
jne .divide_loop |
||||
|
||||
add ecx, edi ; Update amount of characters |
||||
|
||||
mov byte [edi], 0 ; Null terminator |
||||
|
||||
lea edi, [edi-1] ; We incremented the buffer pointer once too much |
||||
|
||||
.swap_loop: |
||||
cmp esi, edi |
||||
jae .done_swapping |
||||
movzx eax, BYTE [edi] |
||||
movzx edx, BYTE [esi] |
||||
mov BYTE [edi], dl |
||||
mov BYTE [esi], al |
||||
sub edi, 1 |
||||
add esi, 1 |
||||
jmp .swap_loop |
||||
|
||||
.done_swapping: |
||||
|
||||
pop ebp |
||||
pop esi |
||||
pop edx |
||||
;pop ecx |
||||
pop edi |
||||
pop eax |
||||
ret |
||||
@ -0,0 +1,160 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||||
; 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 |
||||
Binary file not shown.
Loading…
Reference in new issue