home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 23 / IOPROG_23.ISO / SOFT / ASM / BCDASM.ZIP / BCDASM / SRC / BCDP2B.ASM < prev    next >
Encoding:
Assembly Source File  |  1997-06-03  |  6.2 KB  |  224 lines

  1.     title    BCDASM -- Copyright 1997, Morten Elling
  2.     subttl    Convert packed signed BCDs to/from signed binary
  3.  
  4.     include model.inc
  5.     include modelt.inc
  6.     include bcd.ash
  7.  
  8.     @CODESEG
  9.  
  10. ;//////////////////////////////////////////////////////////////////////
  11. ;//    Name    bcdP2b
  12. ;//    Desc    Convert packed signed BCD to signed binary.
  13. ;//
  14. ;//
  15. ;//    Entry    Passed args
  16. ;//    Exit    Signed binary value returned to destination.
  17. ;//        Acc undefined.
  18. ;//
  19. ;//    Note    The parameter [dstsz] which indicates the byte size
  20. ;//        of the binary destination, must be even-sized and 
  21. ;//        large enough to ensure no overflow during the 
  22. ;//        conversion. A qword (8 bytes) is required to convert
  23. ;//        a tbyte (10 bytes) source BCD.
  24. ;//
  25. ;//    ToDo    Return error if overflow/loss of significance/bad size.
  26.  
  27. bcdP2b    proc
  28. arg    dstBIN    :dataptr, \    ; Addr of binary destination
  29.     dstsz    :@uint, \    ; Byte size of dest. (see note)
  30.     srcBCD    :dataptr, \    ; Addr of source BCD
  31.     srcsz    :@uint        ; Byte size of src
  32. @uses    ds,es,rsi,rdi,rbx,rcx,rdx,rax
  33. ;.
  34.     @cld            ; String ops forward
  35.     @LDS  rsi, [srcBCD]
  36.     @LES  rdi, [dstBIN]
  37.  
  38. ; ----- Zero destination
  39.     mov   rcx, [dstsz]
  40.     sub   al, al        ; Zero al
  41.     rep   stosb
  42.  
  43. ; ----- Skip non-significant zeros in src
  44.     mov   rcx, [srcsz]
  45.     dec   rcx
  46.     add   rsi, rcx        ; -> Sign byte
  47. @@skpz:    dec   rsi        ; Work towards LSB in source
  48.     cmp   al, [rsi]        ; BCD digit pair zero?
  49.     loopz @@skpz        ; Yes, keep going
  50.     jnz sh @@add_digits    ; No, jump into loop
  51.     jmp sh @@end        ; Exit if src is zero
  52.  
  53.  
  54. ; -----    Multiply destination by 100
  55. @@loop_top:
  56.     mov   rcx, [dstsz]
  57.     shr   rcx, 1        ; No. of words to process
  58.     sub   rbx, rbx        ; Clear hi-order
  59. @@x100: mov   AX, @ES [rdi]    ; Get a binary word
  60.     mov   rdx, 100d         ; Set up to multiply
  61.     mul   DX        ;   by 100, product in dx:ax
  62.     add   AX, BX        ; Add hi-order from prev. loop
  63.     adc   DX, 00h        ; Increment dx if carry
  64.     stosW            ; Store AX to destination
  65.     mov   BX, DX        ; Save hi-order for next loop
  66.     loop  @@x100        ; Loop until done
  67.     ; test    DX, DX        ; Possible modification:
  68.     ; jnz sh @@err        ;   error if loss of significance
  69.  
  70. ; ----- Add in next BCD digit pair
  71. @@add_digits:
  72.     mov   rdi,@uiptr [dstBIN] ; Point to destination[0]
  73.     mov   al, [rsi]        ; Get two digits of source
  74.     mov   ah, al        ; Make unpacked BCD
  75.     and   al, 0fh
  76.     @shr  ah, 4
  77.     aad            ; Convert to binary in ax
  78.     add   @ES [rdi], AX    ; Add to destination (no carry
  79.     ; since dest. is a multiple of 100, and ax is max. 99)
  80.     dec   rsi        ; Work towards LSB of src
  81.     cmp   rsi, @uiptr [srcBCD]
  82.     jae   @@loop_top
  83.  
  84.  
  85. ; ----- The number has been converted, now test source's sign.
  86. ;    If positive, we're done, otherwise negate the destination
  87. ;    to make two's complement.
  88.  
  89.     add   rsi, [srcsz]
  90.     test  @bptr [rsi], 80h
  91.     jz sh @@end        ; Exit if source positive
  92.     mov   rcx, [dstsz]
  93.     shr   rcx, 1        ; No. of words to process
  94.     clc            ; Clear carry in
  95. @@ngt:    mov   rax, 0        ; Subtract from zero
  96.     sbb   rax, @ES [rdi]    ;   and propagate the carry
  97.     stosW            ; Store AX to destination
  98.     loop  @@ngt        ; Loop until done
  99.  
  100. @@end:    RET
  101. bcdP2b    endp
  102.  
  103.  
  104. ;//////////////////////////////////////////////////////////////////////
  105. ;//    Name    bcdB2p
  106. ;//    Desc    Convert signed binary to packed signed BCD.
  107. ;//
  108. ;//
  109. ;//    Entry    Passed args
  110. ;//    Exit    Acc > 0: Packed signed BCD returned to destination
  111. ;//        Acc = 0: Error (bad srcsz)
  112. ;//
  113. ;//    Note    The parameter [srcsz] which indicates the byte size of
  114. ;//        the binary source must be even (min. 2), and contain
  115. ;//        no more significant bits than can be converted to
  116. ;//        packed BCD format without overflow (for example, max.
  117. ;//        59 significant bits of a qword, plus sign bit).
  118. ;//
  119. ;//    ToDo    Return error if overflow/loss of significance.
  120.  
  121.     MAX_SIZEOF_BIN = 20h
  122.  
  123. bcdB2p    proc
  124. arg    dstBCD    :dataptr, \    ; Addr of destination BCD
  125.     dstsz    :@uint, \    ; Byte size of dst
  126.     srcBIN    :dataptr, \    ; Addr of source binary
  127.     srcsz    :@uint        ; Byte size of src (even, min. 2)
  128. local    @@src    :byte :MAX_SIZEOF_BIN ; Work buffer
  129. @uses    ds,es,rsi,rdi,rbx,rcx,rdx
  130. ;.
  131. ; ----- Check size parameter
  132.     mov   rax, [srcsz]
  133.     shr   rax, 1
  134.     jbe sh @@err
  135.     add   rax, rax
  136.     cmp   rax, MAX_SIZEOF_BIN
  137.     jbe sh @@cpy
  138. @@err:    sub   rax, rax
  139.     jmp   @@ret
  140.  
  141. ; ----- Copy src to local storage
  142. @@cpy:    xchg  rbx, rax        ; rbx = size of src
  143.     @cld            ; String ops forward
  144.     @LDS  rsi, [srcBIN]
  145.     @LDSEGM es, ss, rdi
  146.     lea   rdi, [@@src]
  147.     mov   rcx, rbx
  148.     rep   movsb
  149.  
  150. ; ----- Zero destination
  151.     @LES  rdi, [dstBCD]
  152.     mov   rcx, [dstsz]
  153.     sub   al, al
  154.     rep   stosb
  155.  
  156. ; ----- Load src pointer
  157.     test  @bptr [rsi-1], 80h ; Test src's sign
  158.     if @isStackFar
  159.     @LDSEGM ds, ss, rsi
  160.     endif
  161.     lea   rsi, [@@src]
  162.     jns sh @@cvt1        ; sf = 0 if positive
  163.  
  164. ; ----- Negate source to get abs. value
  165.     mov   rcx, rbx
  166.     ; cf=0 after 'test'
  167. @@neg:    mov   al, 00h
  168.     sbb   al, [rsi]
  169.     mov   [rsi], al
  170.     inc   rsi
  171.     loop  @@neg
  172.     ; Set destination negative
  173.     or    @bptr @ES [rdi-1], 80h
  174.     ;
  175. @@cvt1: mov   rdi, @uiptr [dstBCD]
  176.  
  177.  
  178. ; ----- Perform the conversion by repeatedly dividing
  179. ;    the binary source by 100 to extract 2 BCD digits
  180. ;    on each loop (uses shift-and-subtract algorithm)
  181. @@looptop:
  182.     ; Entry here: rdi -> destination
  183.     mov   rdx, rbx        ; No. of bytes in source
  184.     @shl  rdx, 3        ; * 8 = no. of bits in source
  185.     sub   rax, rax        ; Clear remainder
  186.     lea   rsi, [@@src]    ; Addr of source
  187. @@shl:    dec   rdx        ; Decrement bit counter
  188.     js sh @@stor        ; Loop done when < 0
  189.     mov   rcx, rbx        ; Loop count =
  190.     shr   rcx, 1        ;   no. of source words, cf=0
  191.     @alignn
  192. @@shm:    rcl   @wptr [rsi], 1    ; Rotate word thru carry left
  193.     inc   rsi        ; Step
  194.     inc   rsi        ;   source pointer
  195.     loop  @@shm        ; Shift whole source left
  196.     rcl   rax, 1        ; Accumulate remainder in acc
  197.     ;
  198.     sub   rsi, rbx        ; Point to @@src[0]
  199.     cmp   rax, 100d        ; Compare acc against divisor
  200.     jb    @@shl        ; Not yet
  201.     sub   rax, 100d        ; One hit
  202.     inc   @bptr [rsi]    ; Update quotient (in low source)
  203.     jmp   @@shl        ; And keep going
  204.  
  205. ; ----- Store 2 BCD digits (acc = source MOD 100)
  206. @@stor: aam            ; Convert ax to unpacked BCD
  207.     @shl  ah, 4        ; Convert un- to packed
  208.     or    al, ah        ; Pack two BCD digits in al
  209.     stosb            ; Store al to destination
  210.  
  211. ; ----- Check if quotient is zero
  212.     ; rsi -> @@src[0]
  213.     mov   rcx, rbx
  214.     sub   al, al
  215.     dec   rsi
  216. @@qzr:    inc   rsi
  217.     or    al, [rsi]
  218.     loopz @@qzr
  219.     jnz   @@looptop     ; Keep going until quotient = 0
  220.     mov   rax, 1
  221. @@ret:    RET
  222. bcdB2p    endp
  223.  
  224.     END