;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 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