Advertisement
Guest User

Arbitrary Precision ADD

a guest
Apr 18th, 2019
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // I am writing this on phone and from memory... so this won’t compile but I’ll comment so you can work out what is happening and fix it
  2.  
  3. void arbitrary_add(uint32_t *a, uint32_t *b, uint32_t *dst, size_t size)
  4. {
  5. // GCC’s asm wrapper
  6. __asm__(
  7.       ".intel_syntax;" // What flavour of assembly we are using
  8.       <remainder of assembly code here>
  9.       <I couldn’t be bothered to type in quotes on my phone so it is just below>
  10.       ".att_syntax;"
  11.       : // No outputs
  12.       : "c"(size), “b”(a), “s”(b), “d”(dst)
  13.       : "ecx",eax,edx,ebx,esi,edi); // Clobbered registers
  14.  
  15. }
  16.  
  17. ; Document our register choices
  18. ; ecx = counter
  19. ; eax = scratch
  20. ; edx = counter
  21. ; ebx = source A
  22. ; esi = source B
  23. ; edi = dst
  24.  
  25. ; Assume that we have normalised vectors ebx, esi and edi to all be the same length (in practice you might need to add one extra value of zero to each of the vectors to allow for overflow)
  26.  
  27. ; At this point GCC will push to the stack the original values in our clobbered registers and restore their value at the end for us
  28. ; GCC will then load ECX, EBX, ESI and EDI with the pointers for size, a, b, and dst
  29.  
  30.  
  31. ; Check if size > 0
  32. .initial_size_check
  33.     CMP ecx, 0.                ; compare to zero
  34.     JE .epilogue.              ; bail if equal
  35.  
  36. ; Normally you can freely use “ADD”, “CMP” etc in our loop conditions and increment
  37. ; However, we want to preserve the carry flag so I have written a contrived loop
  38. ; where I only use “DEC” and “INC” because they preserve the carry flag by design
  39.  
  40. XOR edx, edx                   ; edx is going to count up, whilst ecx counts down
  41. CLC                            ; clear carry flag
  42. .loop_body:
  43.     ; Each loop iteration is going to perform dst[i] = a[i] + b[i] + carry flag
  44.     MOV eax, dword [ebx + edx] ; load value from A vector
  45.     ADC eax, dword [esi + edx] ; add with carry A and value from B vector
  46.     MOV dword [edi + edx], eax ; store result into dst vector
  47.  
  48. .loop_increment:
  49.     inc edx                    ; increment our counter
  50.     dec ecx                    ; decrement our size (this sets zero flag appropriately)
  51.  
  52. .loop_condition:
  53.     JNZ .loop_body             ; Can’t use the natural “Jump Above or Equal” because it relies on carry flag
  54.  
  55. .epilogue
  56. ; At this point dst contains the addition of A and B!
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement