Fast IFS using RPN notation
python
c
x86-64
nasm
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.

rpn_lib.asm 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. ; TODO Use memory area given in argument to preserve stack between calls
  2. [bits 64]
  3. ; local variables macro
  4. %define stack_size [rbp - 8]
  5. %define stack_base [rbp - 16]
  6. %define brkinit [rbp - 24]
  7. %define args_ptr [rbp - 32]
  8. %define stack_cur r11
  9. ; push & pop the RPN stack macros
  10. ; check if stack full, then push value
  11. %macro rpn_push 1
  12. inc stack_cur
  13. cmp stack_cur, stack_size
  14. jl %%end
  15. xor stack_cur, stack_cur
  16. %%end:
  17. mov [r10 + stack_cur * 8], %1
  18. %endmacro
  19. ; check if stack empty, then pop value
  20. %macro rpn_pop 1
  21. mov %1, [r10 + stack_cur * 8]
  22. cmp stack_cur, 0
  23. jg %%end
  24. mov stack_cur, stack_size
  25. %%end:
  26. dec stack_cur
  27. %endmacro
  28. ; define a label with code portion size
  29. ; and set global
  30. %macro part_sz 1
  31. %1_sz: dq $ - %1
  32. global %1
  33. global %1_sz
  34. %endmacro
  35. section .data
  36. rpn_exec:
  37. ; unsigned long int rpn_exec(unsigned long int stack_size, unsigned long args)
  38. ; rdi -> stack size (in values (64 bits))
  39. ; rsi -> args pointers
  40. enter 32, 0
  41. mov stack_size, rdi
  42. mov args_ptr, rsi
  43. mov r10, rdx ; r10 is stack base
  44. xor rdx, rdx
  45. mov brkinit, rdx
  46. cmp r10, 0
  47. jne .nobrk
  48. ; if stack is NULL allocate using brk
  49. mov rax, 0x0C
  50. xor rdi, rdi ; get brk
  51. syscall
  52. mov brkinit, rax
  53. mov rdi, stack_size
  54. shl rdi, 3 ; mul 8
  55. add rdi, rax
  56. mov rax, 0x0C
  57. syscall ; new brk
  58. cmp rax, -1
  59. jne .cont
  60. leave
  61. ret
  62. .cont:
  63. mov rcx, stack_size
  64. mov rdi, brkinit
  65. xor rax, rax
  66. .bzero:
  67. stosq
  68. loop .bzero
  69. mov r10, brkinit
  70. .nobrk:
  71. xor stack_cur, stack_cur ; r11 is stack item counter
  72. part_sz rpn_exec
  73. rpn_exec_ret:
  74. rpn_pop rax
  75. mov rdi, brkinit
  76. cmp rdi, 0
  77. jne .end
  78. push rax
  79. mov rax, 0x0C
  80. mov rdi, brkinit
  81. syscall
  82. pop rax
  83. .end:
  84. leave
  85. ret
  86. part_sz rpn_exec_ret
  87. rpn_value:
  88. mov rax, strict qword 0x12345678
  89. rpn_push rax
  90. part_sz rpn_value
  91. rpn_arg:
  92. mov rax, strict qword 0x12345678
  93. mov rsi, 8
  94. mul rsi
  95. mov rsi, args_ptr
  96. add rsi, rax
  97. mov rax, [rsi]
  98. rpn_push rax
  99. part_sz rpn_arg
  100. rpn_add:
  101. rpn_pop rax
  102. rpn_pop rbx
  103. add rax, rbx
  104. rpn_push rax
  105. part_sz rpn_add
  106. rpn_sub:
  107. rpn_pop rbx
  108. rpn_pop rax
  109. sub rax, rbx
  110. rpn_push rax
  111. part_sz rpn_sub
  112. rpn_mul:
  113. rpn_pop rbx
  114. rpn_pop rax
  115. mul rbx
  116. rpn_push rax
  117. part_sz rpn_mul
  118. rpn_div:
  119. rpn_pop rbx
  120. rpn_pop rax
  121. xor rdx, rdx
  122. test rbx, rbx
  123. jz .zerodiv
  124. div rbx
  125. jmp .end
  126. .zerodiv: xor rax, rax
  127. .end:
  128. rpn_push rax
  129. part_sz rpn_div
  130. rpn_mod:
  131. rpn_pop rbx
  132. rpn_pop rax
  133. xor rdx, rdx
  134. test rbx, rbx
  135. jz .zerodiv
  136. div rbx
  137. jmp .end
  138. .zerodiv: xor rax, rax
  139. .end:
  140. rpn_push rdx
  141. part_sz rpn_mod
  142. rpn_neg:
  143. rpn_pop rax
  144. neg rax
  145. rpn_push rax
  146. part_sz rpn_neg
  147. rpn_not:
  148. rpn_pop rax
  149. not rax
  150. rpn_push rax
  151. part_sz rpn_not
  152. rpn_and:
  153. rpn_pop rbx
  154. rpn_pop rax
  155. and rax, rbx
  156. rpn_push rax
  157. part_sz rpn_and
  158. rpn_or:
  159. rpn_pop rbx
  160. rpn_pop rax
  161. or rax, rbx
  162. rpn_push rax
  163. part_sz rpn_or
  164. rpn_xor:
  165. rpn_pop rbx
  166. rpn_pop rax
  167. xor rax, rbx
  168. rpn_push rax
  169. part_sz rpn_xor
  170. rpn_shl:
  171. rpn_pop rcx
  172. rpn_pop rax
  173. cmp rcx, 64
  174. jge .zero
  175. shl rax, cl
  176. jmp .end
  177. .zero:
  178. xor rax, rax
  179. .end:
  180. rpn_push rax
  181. part_sz rpn_shl
  182. rpn_shr:
  183. rpn_pop rcx
  184. rpn_pop rax
  185. cmp rcx, 64
  186. jge .zero
  187. shr rax, cl
  188. jmp .end
  189. .zero:
  190. xor rax, rax
  191. .end:
  192. rpn_push rax
  193. part_sz rpn_shr
  194. rpn_xchg:
  195. rpn_pop rbx
  196. rpn_pop rax
  197. rpn_push rbx
  198. rpn_push rax
  199. part_sz rpn_xchg
  200. rpn_dup:
  201. rpn_pop rax
  202. rpn_push rax
  203. rpn_push rax
  204. part_sz rpn_dup
  205. rpn_pop_op:
  206. rpn_pop rax
  207. part_sz rpn_pop_op
  208. section .text