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.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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 .note.GNU-stack noalloc noexec nowrite progbits
  36. section .data
  37. rpn_exec:
  38. ; unsigned long int rpn_exec(unsigned long int stack_size, unsigned long args, unsigned long int *stack)
  39. ; rdi -> stack size (in values (64 bits))
  40. ; rsi -> args pointers
  41. ; rdx -> stack pointer or null
  42. enter 32, 0
  43. push rbx ; rbx MUST BE PRESERVED !!! (like r12 to r15 and rbp !)
  44. mov stack_size, rdi
  45. mov args_ptr, rsi
  46. mov r10, rdx ; r10 is stack base
  47. xor rdx, rdx
  48. mov brkinit, rdx
  49. cmp r10, 0
  50. jne .nobrk
  51. ; if stack is NULL allocate using brk
  52. mov rax, 0x0C
  53. xor rdi, rdi ; get brk
  54. syscall
  55. mov brkinit, rax
  56. mov rdi, stack_size
  57. shl rdi, 3 ; mul 8
  58. add rdi, rax
  59. mov rax, 0x0C
  60. syscall ; new brk
  61. cmp rax, -1
  62. jne .cont
  63. leave
  64. ret
  65. .cont:
  66. mov rcx, stack_size
  67. mov rdi, brkinit
  68. xor rax, rax
  69. .bzero:
  70. stosq
  71. loop .bzero
  72. mov r10, brkinit
  73. .nobrk:
  74. xor stack_cur, stack_cur ; r11 is stack item counter
  75. part_sz rpn_exec
  76. rpn_exec_ret:
  77. rpn_pop rax
  78. mov rdi, brkinit
  79. cmp rdi, 0
  80. jne .end
  81. push rax
  82. mov rax, 0x0C
  83. mov rdi, brkinit
  84. syscall
  85. pop rax
  86. .end:
  87. pop rbx
  88. leave
  89. ret
  90. part_sz rpn_exec_ret
  91. rpn_value:
  92. mov rax, strict qword 0x12345678
  93. rpn_push rax
  94. part_sz rpn_value
  95. rpn_arg:
  96. mov rax, strict qword 0x12345678
  97. mov rsi, 8
  98. mul rsi
  99. mov rsi, args_ptr
  100. add rsi, rax
  101. mov rax, [rsi]
  102. rpn_push rax
  103. part_sz rpn_arg
  104. rpn_add:
  105. rpn_pop rax
  106. rpn_pop rbx
  107. add rax, rbx
  108. rpn_push rax
  109. part_sz rpn_add
  110. rpn_sub:
  111. rpn_pop rbx
  112. rpn_pop rax
  113. sub rax, rbx
  114. rpn_push rax
  115. part_sz rpn_sub
  116. rpn_mul:
  117. rpn_pop rbx
  118. rpn_pop rax
  119. mul rbx
  120. rpn_push rax
  121. part_sz rpn_mul
  122. rpn_div:
  123. rpn_pop rbx
  124. rpn_pop rax
  125. xor rdx, rdx
  126. test rbx, rbx
  127. jz .zerodiv
  128. div rbx
  129. jmp .end
  130. .zerodiv: xor rax, rax
  131. .end:
  132. rpn_push rax
  133. part_sz rpn_div
  134. rpn_mod:
  135. rpn_pop rbx
  136. rpn_pop rax
  137. xor rdx, rdx
  138. test rbx, rbx
  139. jz .zerodiv
  140. div rbx
  141. jmp .end
  142. .zerodiv: xor rax, rax
  143. .end:
  144. rpn_push rdx
  145. part_sz rpn_mod
  146. rpn_neg:
  147. rpn_pop rax
  148. neg rax
  149. rpn_push rax
  150. part_sz rpn_neg
  151. rpn_not:
  152. rpn_pop rax
  153. not rax
  154. rpn_push rax
  155. part_sz rpn_not
  156. rpn_and:
  157. rpn_pop rbx
  158. rpn_pop rax
  159. and rax, rbx
  160. rpn_push rax
  161. part_sz rpn_and
  162. rpn_or:
  163. rpn_pop rbx
  164. rpn_pop rax
  165. or rax, rbx
  166. rpn_push rax
  167. part_sz rpn_or
  168. rpn_xor:
  169. rpn_pop rbx
  170. rpn_pop rax
  171. xor rax, rbx
  172. rpn_push rax
  173. part_sz rpn_xor
  174. rpn_shl:
  175. rpn_pop rcx
  176. rpn_pop rax
  177. cmp rcx, 64
  178. jge .zero
  179. shl rax, cl
  180. jmp .end
  181. .zero:
  182. xor rax, rax
  183. .end:
  184. rpn_push rax
  185. part_sz rpn_shl
  186. rpn_shr:
  187. rpn_pop rcx
  188. rpn_pop rax
  189. cmp rcx, 64
  190. jge .zero
  191. shr rax, cl
  192. jmp .end
  193. .zero:
  194. xor rax, rax
  195. .end:
  196. rpn_push rax
  197. part_sz rpn_shr
  198. rpn_xchg:
  199. rpn_pop rbx
  200. rpn_pop rax
  201. rpn_push rbx
  202. rpn_push rax
  203. part_sz rpn_xchg
  204. rpn_dup:
  205. rpn_pop rax
  206. rpn_push rax
  207. rpn_push rax
  208. part_sz rpn_dup
  209. rpn_pop_op:
  210. rpn_pop rax
  211. part_sz rpn_pop_op
  212. section .text