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.

159 line
3.0 KiB

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ; Converts integer to string
  3. ; IN: eax = number to convert
  4. ; IN: edi = base of string buffer
  5. ; OUT: ecx = number of characters written to buffer
  6. IntToString:
  7. push eax
  8. push esi
  9. push edx
  10. push edi
  11. push ebp
  12. mov ecx, esi ; store negative original buffer base
  13. neg ecx ; (used for counting amount of characters)
  14. test eax, eax
  15. jns .not_negative
  16. mov BYTE [esi], '-'
  17. neg eax
  18. add esi, 1
  19. .not_negative:
  20. mov edi, esi ; store pointer after potential negative sign character
  21. mov ebp, 0xcccccccd ; ebp = 32 bit multiplicative reciprocal of 10
  22. .divide_loop:
  23. mov ebx, eax ; save number in ebx
  24. mul ebp
  25. shr edx, 3 ; edx = quotient
  26. lea eax, [edx + edx*4] ; eax = quotient * 10 = (number - remainder)
  27. add eax, eax ; |
  28. sub ebx, eax ; ebx = number - (number - remainder) = remainder
  29. add ebx, '0' ; remainder is our digit, turn it ASCII
  30. mov BYTE [esi], bl ; store ASCII digit to buffer
  31. lea esi, [esi+1]
  32. mov eax, edx ; We need quotient in eax for 'mul'
  33. test eax, eax
  34. jne .divide_loop
  35. add ecx, esi ; Update amount of characters
  36. mov byte [esi], 0x00 ; Add null terminator to end of string
  37. lea esi, [esi-1] ; We incremented the buffer pointer once too much
  38. .swap_loop:
  39. cmp edi, esi
  40. jae .done_swapping
  41. movzx eax, BYTE [esi]
  42. movzx edx, BYTE [edi]
  43. mov BYTE [esi], dl
  44. mov BYTE [edi], al
  45. sub esi, 1
  46. add edi, 1
  47. jmp .swap_loop
  48. .done_swapping:
  49. pop ebp
  50. pop edi
  51. pop edx
  52. pop esi
  53. pop eax
  54. ret
  55. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  56. ; Right justifies source string within the given justification width
  57. ; IN: esi = base of string buffer
  58. ; IN: edx = justification width
  59. ; IN: ecx = string length
  60. ; IN: al = padding char
  61. ; ASSUMES: that the justification width > string length
  62. ; ASSUMES: that the size of the string buffer > justification width
  63. RightJustifyString:
  64. pushad
  65. pushfd
  66. lea edi, [esi + edx-1]
  67. lea esi, [esi + ecx-1]
  68. sub edx, ecx
  69. std ; Move string from the end
  70. rep movsb ; |
  71. mov ecx, edx
  72. rep stosb ; Pad with AL
  73. popfd
  74. popad
  75. ret
  76. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  77. ; Copies ecx bytes
  78. ; IN: esi = source
  79. ; IN: edi = destination
  80. ; IN: ecx = number of bytes to copy
  81. CopyData:
  82. pushad
  83. mov edx, ecx
  84. and edx, 11b
  85. shr ecx, 2
  86. ; ecx = quotient, edx = remainder
  87. rep movsd
  88. mov ecx, edx
  89. rep movsb
  90. popad
  91. ret
  92. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  93. ; Puts the stringified version of eax on the stack
  94. ; IN: esi = base of string
  95. ; IN: ecx = string length
  96. ; IN: ah = character attributes
  97. PrintString:
  98. push ecx
  99. push eax
  100. push edi
  101. push esi
  102. .print_loop:
  103. mov al, byte [esi]
  104. mov word [edi], ax
  105. lea esi, [esi+1]
  106. lea edi, [edi+2]
  107. sub ecx, 1
  108. jnz .print_loop
  109. pop esi
  110. pop edi
  111. pop eax
  112. pop ecx
  113. ret