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 rivejä
3.0 KiB
160 rivejä
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 |