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

  1.     title    BCDUU -- Copyright 1997, Morten Elling
  2.     subttl    Routines to handle unsigned un-packed BCDs
  3.  
  4.     include    model.inc
  5.     include    modelt.inc
  6.     include bcduu.ash
  7.  
  8.     @CODESEG
  9.  
  10. ;//////////////////////////////////////////////////////////////////////
  11. ;//    Name    BCDUUmov
  12. ;//    Desc    Move (copy) an un-packed BCD value.
  13. ;//
  14. ;//
  15. ;//    Entry    Passed args
  16. ;//    Exit    Destination = source. Acc undefined.
  17.  
  18. BCDUUmov proc
  19. arg    dstBCD    :dataptr, \    ; Addr of dest. BCD (size = srcsz)
  20.     srcBCD    :dataptr, \    ; Addr of source BCD
  21.     srcsz    :@uint        ; Byte size of source
  22. @uses    ds,es,rsi,rdi,rcx
  23. ;.
  24.     @cld            ; String ops forward
  25.     @LDS  rsi, [srcBCD]
  26.     @LES  rdi, [dstBCD]
  27.     mov   rcx, [srcsz]
  28.     rep   movsb
  29.     RET
  30. BCDUUmov endp
  31.  
  32.  
  33. ;//////////////////////////////////////////////////////////////////////
  34. ;//    Name    BCDUUadd
  35. ;//    Desc    Add two unpacked unsigned BCD numbers (dst += src).
  36. ;//
  37. ;//
  38. ;//    Entry    Passed args
  39. ;//    Exit    Sum of dest. and source returned to destination.
  40. ;//        Accumulator (and cf flag) determined:
  41. ;//        Acc = 0: No carry
  42. ;//        Acc = 1: Carry (overflow)
  43. ;//
  44. ;//    Note    Destination and source may be the same.
  45.  
  46. BCDUUadd proc
  47. arg    dstBCD    :dataptr, \    ; Addr of dest. BCD (size = srcsz)
  48.     srcBCD    :dataptr, \    ; Addr of source BCD
  49.     srcsz    :@uint        ; Byte size of source
  50. @uses    ds,es,rsi,rdi,rcx
  51. ;.
  52.     @cld            ; String ops forward
  53.     @LDS  rsi, [srcBCD]
  54.     @LES  rdi, [dstBCD]
  55.     mov   rcx, [srcsz]    ; Byte size = loop count
  56.     clc            ; Clear carry in
  57. @@nxta:    lodsb            ; Get one digit of source
  58.     adc   al, @ES [rdi]    ; Add digit of dest + carry
  59.     aaa            ; Adjust to unpacked BCD format
  60.     stosb            ; Store al to destination
  61.     loop  @@nxta        ; Loop until done
  62.     ; Carry set by AAA
  63.     ; if overflow (ah > 0)
  64.     sbb   rax, rax        ; Acc=0,cf=0 or acc=-1,cf=1
  65.     neg   rax        ; Acc=0,cf=0 or acc=1,cf=1
  66.     RET
  67. BCDUUadd endp
  68.  
  69.  
  70. ;//////////////////////////////////////////////////////////////////////
  71. ;//    Name    BCDUUsub
  72. ;//    Desc    Subtract two unpacked unsigned BCD numbers (dst -= src)
  73. ;//
  74. ;//
  75. ;//    Entry    Passed args
  76. ;//    Exit    Difference (dest - source) returned to destination.
  77. ;//        Accumulator (and cf flag) determined:
  78. ;//        Acc = 0: No borrow
  79. ;//        Acc = 1: Borrow (underflow)
  80. ;//
  81. ;//    Note    Destination and source may be the same.
  82.  
  83. BCDUUsub proc
  84. arg    dstBCD    :dataptr, \    ; Addr of dest. BCD (size = srcsz)
  85.     srcBCD    :dataptr, \    ; Addr of source BCD
  86.     srcsz    :@uint        ; Byte size of source
  87. @uses    ds,es,rsi,rdi,rcx
  88. ;.
  89.     @cld            ; String ops forward
  90.     @LDS  rsi, [srcBCD]
  91.     @LES  rdi, [dstBCD]
  92.     mov   rcx, [srcsz]    ; Byte size = loop count
  93.     clc            ; Clear carry in
  94. @@nxts: mov   al, @ES [rdi]    ; Get one digit of dest
  95.     sbb   al, [rsi]        ; Subtract source and carry
  96.     aas            ; Adjust to unpacked BCD format
  97.     stosb            ; Store al to destination
  98.     inc   rsi        ; Step src pointer
  99.     loop  @@nxts        ; Loop until done
  100.     ; Carry set by AAS
  101.     ; if underflow (ah < 0)
  102.     sbb   rax, rax        ; Acc=0,cf=0 or acc=-1,cf=1
  103.     neg   rax        ; Acc=0,cf=0 or acc=1,cf=1
  104.     RET
  105. BCDUUsub endp
  106.  
  107.  
  108. ;//////////////////////////////////////////////////////////////////////
  109. ;//    Name    BCDUUu2p
  110. ;//    Desc    Convert un-packed unsigned BCD to packed unsigned BCD.
  111. ;//
  112. ;//
  113. ;//    Entry    Passed args
  114. ;//    Exit    Packed BCD returned to destination.
  115. ;//        Acc > 0: No error.
  116. ;//        Acc = 0: High word of source contains information
  117. ;//             that cannot be converted.
  118. ;//
  119. ;//    Note    Assumes source size is twice that of destination.
  120.  
  121. BCDUUu2p proc
  122. arg    dstBCD    :dataptr, \    ; Addr of dest. BCD (size = srcsz/2)
  123.     srcBCD    :dataptr, \    ; Addr of unpacked source BCD
  124.     srcsz    :@uint        ; Byte size of source
  125. @uses    ds,es,rsi,rdi,rcx
  126. ;.
  127.     @cld            ; String ops forward
  128.     @LDS  rsi, [srcBCD]
  129.     @LES  rdi, [dstBCD]
  130.     mov   rcx, [srcsz]    ; Byte size = loop count
  131. @@up1:    lodsW            ; Get two digits of source
  132.     @shl  ah, 4        ; Shift nibble into position
  133.     or    al, ah        ; Pack two digits into al
  134.     stosb            ; Store al to destination
  135.     loop  @@up1        ; Loop until done
  136.  
  137. ; ----- Return 0 or 1
  138.     neg   al        ; Set carry if al <> 0
  139.     sbb   rax, rax
  140.     inc   rax
  141.     RET
  142. BCDUUu2p endp
  143.  
  144.  
  145. ;//////////////////////////////////////////////////////////////////////
  146. ;//    Name    BCDUUu2a
  147. ;//    Desc    Convert unpacked unsigned BCD to decimal Ascii.
  148. ;//        Outputs at least one character.
  149. ;//
  150. ;//
  151. ;//    Entry    Passed args
  152. ;//    Exit    Zero-terminated Ascii string returned to destination.
  153. ;//        Acc = length of destination string (less trailing 0).
  154. ;//
  155. ;//    Note    Maximum output to the destination string equals the
  156. ;//        BCD's byte size plus 1.
  157.  
  158. BCDUUu2a proc
  159. arg    pStr    :dataptr, \    ; Addr of AsciiZ dest.
  160.     srcBCD    :dataptr, \    ; Addr of source BCD
  161.     srcsz    :@uint        ; Byte size of source BCD
  162. @uses    ds,es,rsi,rdi,rcx
  163. ;.
  164.     @cld            ; String ops forward
  165.     @LDS  rsi, [srcBCD]
  166.     @LES  rdi, [pStr]
  167.     mov   rcx, [srcsz]
  168.  
  169. ; ----- Skip insignificant zeros
  170.     add   rsi, rcx
  171. @@ua1:    dec   rsi
  172.     mov   al, [rsi]
  173.     test  al, al
  174.     loopz @@ua1
  175.     inc   rcx        ; Output at least one digit
  176.  
  177. ; ----- Convert BCD
  178. @@ua2:    mov   al, [rsi]        ; Get unpacked BCD digit
  179.     dec   rsi        ; Decrement src. index
  180.     or    al, '0'        ; Convert to Ascii
  181.     stosb            ; Store al to destination
  182.     loop  @@ua2        ; Loop until done
  183.  
  184. ; ----- Zero-terminate string
  185. ;    and return its length
  186.     sub   al, al
  187.         stosb
  188.     lea   rax, [rdi-1]
  189.     sub   rax, @uiptr [pStr]
  190.     RET
  191. BCDUUu2a endp
  192.  
  193.  
  194. ;//////////////////////////////////////////////////////////////////////
  195. ;//    Name    BCDUUmul
  196. ;//    Desc    Multiply two unpacked unsigned BCDs (dst *= src).
  197. ;//
  198. ;//
  199. ;//    Entry    Passed args
  200. ;//    Exit    Double-size unpacked unsigned BCD product returned to
  201. ;//        destination _replacing_ the multiplicand.
  202. ;//        Acc undefined.
  203. ;//
  204. ;//    Note    Both BCD operands must be defined as double-size,
  205. ;//        where the high-order is undefined (because the result
  206. ;//        is returned as double-precision, and the multiplier
  207. ;//        provides temporary work space for this procedure).
  208. ;//
  209. ;//        See bcdImul for details on algorithm.
  210.  
  211. BCDUUmul proc
  212. arg    dstBCD    :dataptr, \    ; Addr of BCD multiplicand
  213.     srcBCD    :dataptr, \    ; Addr of BCD multiplier
  214.     srcsz    :@uint        ; Byte size of each BCD (double-size)
  215. @uses    ds,es,rsi,rdi,rbx,rcx,rdx,rax
  216. ;.
  217. ; ----- Copy multiplicand to hi(src)
  218.     push  rbp
  219.     @cld            ; String ops forward
  220.     @LDS  rsi, [dstBCD]
  221.     @LES  rdi, [srcBCD]
  222.         mov   rbx, [srcsz]
  223.     mov   rcx, rbx
  224.     shr   rcx, 1
  225.     add   rdi, rcx
  226.     rep   movsb
  227.  
  228. ; ----- Zero-fill destination
  229.     @LES  rdi, [dstBCD]
  230.     mov   rcx, rbx
  231.     sub   al, al
  232.     rep   stosb
  233.  
  234. ; ----- Fix pointers
  235.     @LDS  rsi, [srcBCD]    ; u[0]
  236.     sub   rdi, rbx        ; w[0]
  237.     mov   rdx, rbx
  238.     shr   rbx, 1
  239.     lea   rbp, [rsi+rbx]    ; v[0]
  240.     ; *** No stack frame ***
  241.  
  242.  
  243. ; ----- Perform the multiplication using the
  244. ;    MUL, AAM, ADD, and AAA instructions
  245.     ;
  246.         sub   rbx, rbx          ; i = 0
  247.     @alignn
  248. @@outr: sub   rcx, rcx          ; j = 0
  249.     sub   ah, ah        ; k = 0
  250. @@innr:    push  rdx        ; Save m
  251.     mov   dh, ah        ; Save k (un-packed BCD)
  252.     ife @isUse32
  253.     xchg  rbx, rcx
  254.     mov   ah, [rsi+rbx]    ; Get u[j]
  255.     xchg  rbx, rcx
  256.     xchg  rsi, rbp
  257.     mov   al, [rsi+rbx]    ; Get v[i]
  258.     xchg  rsi, rbp
  259.      else
  260.     mov   ah, [rsi+rcx]
  261.     mov   al, [rbx+rbp]
  262.     endif
  263.     mul   ah        ; t = u[j] * v[i]
  264.     aam
  265.     add   al, dh        ;     + k
  266.     aaa
  267.     add   rbx, rcx
  268.     add   al, @ES [rdi+rbx] ;     + w[i+j]
  269.     aaa
  270.     mov   @ES [rdi+rbx], al ; w[i+j] = t mod 10
  271.     ;mov   ah, ah        ; k     = t div 10
  272.     sub   rbx, rcx        ; Restore i
  273.     pop   rdx        ; Restore m
  274.     inc   rcx        ; j++
  275.     cmp   rcx, rdx        ; j == m?
  276.     jb    @@innr         ; No, repeat inner loop
  277.     ;
  278.     add   rbx, rdx
  279.     mov   @ES [rdi+rbx], ah ; w[i+m] = k
  280.     sub   rbx, rdx        ; Restore i
  281.     inc   rbx        ; i++
  282.     cmp   rbx, rdx        ; i == m?
  283.     jb    @@outr         ; No, repeat outer loop
  284.     ;
  285.     pop   rbp
  286.     ; *** Stack frame restored ***
  287.     RET            ; Return
  288. BCDUUmul endp
  289.  
  290.         END