Advertisement
Guest User

Untitled

a guest
May 28th, 2017
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. .586
  2. .model flat, stdcall
  3. ExitProcess PROTO, dwExitCode:DWORD
  4.  
  5. include module.inc
  6. include \Irvine\Irvine32.inc
  7. includelib \Irvine\kernel32.lib
  8. includelib \Irvine\user32.lib
  9.  
  10.  
  11. .data
  12.   CaptionOut BYTE "Last <<< --- First // ", 0
  13.  
  14.     temp_bcd     dt   ?
  15.     szdecimal    db   32 dup(0)
  16.  
  17.     MyNum REAL8 45.45
  18.    
  19. .code
  20. main PROC
  21.    
  22.     fld MyNum
  23.    
  24.     pushd 100            ;use the stack as storage for this value
  25.  
  26.     fimul dword ptr[esp] ;converts 2 decimal places as 2 more integer digits
  27.     fbstp temp_bcd       ;store the packed BCD integer value
  28.     pop  eax             ;clean the stack of the pushed 100
  29.  
  30. ; ESI will be used for pointing to the packed BCD
  31. ; EDI will be used for pointing to the decimal string
  32.  
  33.    push esi
  34.    push edi
  35.    lea  esi,temp_bcd+9  ;point to the most significant byte
  36.    lea  edi,szdecimal   ;point to the start of the decimal string buffer
  37.    xor  eax,eax
  38.    fwait                ;to ascertain that the transfer of the
  39.                         ;packed BCD is completed
  40.  
  41.    mov  al,[esi]        ;get the byte with the sign code
  42.    dec  esi             ;decrement to next most significant byte
  43.    or   al,al           ;for checking the sign bit
  44.    jns  @F              ;jump if no sign bit
  45.    mov  al,"-"          ;the value is negative
  46.    stosb                ;insert the negative sign
  47.  
  48. @@:
  49.  
  50. ; The next 8 bytes (in this example) will contain the integer digits
  51. ; and the least significant byte will then contain the 2 decimal digits.
  52. ; No leading 0 will be included in the integer portion
  53. ; unless it would be the only integer digit.
  54.  
  55.    mov  ecx,8           ;number of bytes to process for integer digits
  56.  
  57. @@:
  58.  
  59.    mov  al,[esi]        ;get the next byte
  60.    dec  esi             ;adjust the pointer to the next one
  61.    or   al,al           ;for checking if it is 0
  62.    jnz  @F              ;the starting integer digit is now in AL
  63.    dec  ecx             ;adjust the counter of integer bytes
  64.    jnz  @B              ;continue searching for the first integer digit
  65.  
  66. ; If the loop terminates with ECX=0, the integer portion would be 0.
  67. ; A "0" character must be inserted before processing the decimal digits
  68.  
  69.    mov  al,"0"          ;the ASCII 0
  70.    stosb                ;insert it
  71.    mov  al,[esi]        ;get the byte containing the decimal digits
  72.    jmp  decimal_digits
  73.  
  74. @@:
  75.  
  76. ; The first integer byte must be checked to determine
  77. ; if it contains 1 or 2 integer digits
  78.  
  79.    test al,0f0h         ;test if the H.O. nibble contains a digit
  80.    jz   int_digit2      ;if not, process only the L.O. nibble
  81.  
  82. int_digit1:
  83.    ror  ax,4            ;puts the H.O. nibble in the L.O. nibble position
  84.                         ;and saves the L.O. nibble in AH
  85.    add  al,30h          ;convert it to ASCII character
  86.    stosb                ;store this character
  87.    shr  ax,12           ;restores the L.O. nibble in AL
  88.                         ;and also resets the other bits of AX
  89.  
  90. int_digit2:
  91.    add  al,30h          ;convert it to ASCII character
  92.    stosb                ;store this character
  93.    mov  al,[esi]        ;get next byte
  94.    dec  esi             ;adjust the pointer to the next one
  95.    dec  ecx             ;adjust the counter of integer bytes
  96.    jnz  int_digit1      ;continue processing the integer bytes
  97.  
  98. decimal_digits:
  99.    mov  byte ptr [edi],"." ;insert the preferred decimal delimiter
  100.    inc  edi
  101.  
  102. ; If more than 2 decimal digits are required, a counter would be needed
  103. ; to process the necessary bytes.
  104. ; Also, if the number of required decimal digits is not even, the code
  105. ; would have to be altered to insert the decimal delimiter at the
  106. ; proper location.
  107.  
  108.    ror  ax,4            ;puts the H.O. nibble in the L.O. nibble position
  109.                         ;and saves the L.O. nibble in AH
  110.    add  al,30h          ;convert it to ASCII character
  111.    stosb                ;store this character
  112.    shr  ax,12           ;restores the L.O. nibble in AL
  113.                         ;and also resets the other bits of AX
  114.    add  al,30h          ;convert it to ASCII character
  115.    stosw                ;store this character + the terminating 0
  116.  
  117.     INVOKE MessageBoxA, 0, ADDR szdecimal, ADDR CaptionOut, 0
  118.  
  119.     INVOKE ExitProcess,0
  120. main ENDP
  121. END main
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement