primitives.asm 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. ;@+leo-ver=5-thin
  2. ;@+node:caminhante.20211214151146.6: * @file primitives.asm
  3. ;@@nocolor
  4. ;@@language assembly_x86
  5. ;@@tabwidth -2
  6. ;@+others
  7. ;@+node:caminhante.20211214151550.1: ** Utilities
  8. ;@+node:caminhante.20211214151505.1: *3* struc registers
  9. struc registers {
  10. .eax rd 1
  11. .ebx rd 1
  12. .ecx rd 1
  13. .edx rd 1
  14. .esi rd 1
  15. .edi rd 1
  16. }
  17. ;@+node:caminhante.20211214151537.1: *3* macro save_reg
  18. macro save_reg [reg*] {
  19. mov [reg_buffer.#reg], reg
  20. }
  21. ;@+node:caminhante.20211214151544.1: *3* macro restore_reg
  22. macro restore_reg [reg*] {
  23. mov reg, [reg_buffer.#reg]
  24. }
  25. ;@+node:caminhante.20211214151610.1: ** Stack management
  26. ;@+node:caminhante.20211214151640.1: *3* DROP
  27. DROP: dd _enter_native
  28. pop eax
  29. jmp _next_routine
  30. ;@+node:caminhante.20211214151646.1: *3* SWAP
  31. SWAP: dd _enter_native
  32. pop eax
  33. pop ebx
  34. push eax
  35. push ebx
  36. jmp _next_routine
  37. ;@+node:caminhante.20211214151650.1: *3* DUP1
  38. DUP1: dd _enter_native
  39. push dword [esp]
  40. jmp _next_routine
  41. ;@+node:caminhante.20211214151655.1: *3* OVER
  42. OVER: dd _enter_native
  43. push dword [esp+4]
  44. jmp _next_routine
  45. ;@+node:caminhante.20211214151659.1: *3* ROT
  46. ROT: dd _enter_native
  47. pop eax
  48. pop ebx
  49. pop ecx
  50. push ebx
  51. push eax
  52. push ecx
  53. jmp _next_routine
  54. ;@+node:caminhante.20211214151705.1: *3* UNROT
  55. UNROT: dd _enter_native
  56. pop eax
  57. pop ebx
  58. pop ecx
  59. push eax
  60. push ecx
  61. push ebx
  62. jmp _next_routine
  63. ;@+node:caminhante.20211214151709.1: *3* DROP2
  64. DROP2: dd _enter_native
  65. pop eax
  66. pop eax
  67. jmp _next_routine
  68. ;@+node:caminhante.20211214151714.1: *3* DUP2
  69. DUP2: dd _enter_native
  70. mov eax, [esp]
  71. mov ebx, [esp+4]
  72. push ebx
  73. push eax
  74. jmp _next_routine
  75. ;@+node:caminhante.20211214151720.1: *3* SWAP2
  76. SWAP2: dd _enter_native
  77. pop eax
  78. pop ebx
  79. pop ecx
  80. pop edx
  81. push ebx
  82. push eax
  83. push edx
  84. push ecx
  85. jmp _next_routine
  86. ;@+node:caminhante.20211214151726.1: *3* NZDUP
  87. NZDUP: dd _enter_native
  88. mov eax, [esp]
  89. test eax, eax
  90. jz @f
  91. push eax
  92. @@:
  93. jmp _next_routine
  94. ;@+node:caminhante.20211214153126.1: ** Basic arithmetic
  95. ;@+node:caminhante.20211214153135.1: *3* INCR1
  96. INCR1: dd _enter_native
  97. inc dword [esp]
  98. jmp _next_routine
  99. ;@+node:caminhante.20211214153142.1: *3* DECR1
  100. DECR1: dd _enter_native
  101. dec dword [esp]
  102. jmp _next_routine
  103. ;@+node:caminhante.20211214153150.1: *3* INCR4
  104. INCR4: dd _enter_native
  105. add dword [esp], 4
  106. jmp _next_routine
  107. ;@+node:caminhante.20211214153208.1: *3* DECR4
  108. DECR4: dd _enter_native
  109. sub dword [esp], 4
  110. jmp _next_routine
  111. ;@+node:caminhante.20211214153214.1: *3* ADDIT
  112. ADDIT: dd _enter_native
  113. pop eax
  114. add dword [esp], eax
  115. jmp _next_routine
  116. ;@+node:caminhante.20211214153220.1: *3* SUBIT
  117. SUBIT: dd _enter_native
  118. pop eax
  119. sub dword [esp], eax
  120. jmp _next_routine
  121. ;@+node:caminhante.20211214153229.1: *3* MULIT
  122. MULIT: dd _enter_native
  123. pop eax
  124. pop ebx
  125. imul ebx, eax
  126. push eax
  127. jmp _next_routine
  128. ;@+node:caminhante.20211214153247.1: *3* DIVMOD
  129. DIVMOD: dd _enter_native
  130. xor edx, edx
  131. pop ebx
  132. pop eax
  133. idiv ebx
  134. push edx
  135. push eax
  136. jmp _next_routine
  137. ;@+node:caminhante.20211214153326.1: ** Arithmetic tests
  138. ;@+node:caminhante.20211214153335.1: *3* ISEQU
  139. ISEQU: dd _enter_native
  140. pop eax
  141. cmp eax, [esp]
  142. sete al
  143. movzx eax, al
  144. mov [esp], eax
  145. jmp _next_routine
  146. ;@+node:caminhante.20211214153349.1: *3* ISDIF
  147. ISDIF: dd _enter_native
  148. pop eax
  149. cmp eax, [esp]
  150. setne al
  151. movzx eax, al
  152. mov [esp], eax
  153. jmp _next_routine
  154. ;@+node:caminhante.20211214153355.1: *3* LT
  155. LT: dd _enter_native
  156. pop eax
  157. cmp eax, [esp]
  158. setl al
  159. movzx eax, al
  160. mov [esp], eax
  161. jmp _next_routine
  162. ;@+node:caminhante.20211214153401.1: *3* GT
  163. GT: dd _enter_native
  164. pop eax
  165. cmp eax, [esp]
  166. setg al
  167. movzx eax, al
  168. mov [esp], eax
  169. jmp _next_routine
  170. ;@+node:caminhante.20211214153407.1: *3* LE
  171. LE: dd _enter_native
  172. pop eax
  173. cmp eax, [esp]
  174. setle al
  175. movzx eax, al
  176. mov [esp], eax
  177. jmp _next_routine
  178. ;@+node:caminhante.20211214153411.1: *3* GE
  179. GE: dd _enter_native
  180. pop eax
  181. cmp eax, [esp]
  182. setge al
  183. movzx eax, al
  184. mov [esp], eax
  185. jmp _next_routine
  186. ;@+node:caminhante.20211214153418.1: *3* EQU0
  187. EQU0: dd _enter_native
  188. cmp dword [esp], 0
  189. setz al
  190. movzx eax, al
  191. mov [esp], eax
  192. jmp _next_routine
  193. ;@+node:caminhante.20211214153424.1: *3* DIF0
  194. DIF0: dd _enter_native
  195. cmp dword [esp], 0
  196. setnz al
  197. movzx eax, al
  198. mov [esp], eax
  199. jmp _next_routine
  200. ;@+node:caminhante.20211214153429.1: *3* LT0
  201. LT0: dd _enter_native
  202. cmp dword [esp], 0
  203. setl al
  204. movzx eax, al
  205. mov [esp], eax
  206. jmp _next_routine
  207. ;@+node:caminhante.20211214153434.1: *3* GT0
  208. GT0: dd _enter_native
  209. cmp dword [esp], 0
  210. setg al
  211. movzx eax, al
  212. mov [esp], eax
  213. jmp _next_routine
  214. ;@+node:caminhante.20211214153439.1: *3* LE0
  215. LE0: dd _enter_native
  216. cmp dword [esp], 0
  217. setle al
  218. movzx eax, al
  219. mov [esp], eax
  220. jmp _next_routine
  221. ;@+node:caminhante.20211214153444.1: *3* GE0
  222. GE0: dd _enter_native
  223. cmp dword [esp], 0
  224. setge al
  225. movzx eax, al
  226. mov [esp], eax
  227. jmp _next_routine
  228. ;@+node:caminhante.20211214153451.1: *3* AND4
  229. AND4: dd _enter_native
  230. pop eax
  231. and [esp], eax
  232. jmp _next_routine
  233. ;@+node:caminhante.20211214153456.1: *3* OR4
  234. OR4: dd _enter_native
  235. pop eax
  236. or [esp], eax
  237. jmp _next_routine
  238. ;@+node:caminhante.20211214153500.1: *3* NOT4
  239. NOT4: dd _enter_native
  240. not dword [esp]
  241. jmp _next_routine
  242. ;@+node:caminhante.20211214153505.1: *3* NEG4
  243. NEG4: dd _enter_native
  244. neg dword [esp]
  245. jmp _next_routine
  246. ;@+node:caminhante.20211214153530.1: ** Memory operations
  247. ;@-others
  248. ;; TODO
  249. POKE4: dd _enter_native
  250. pop ebx
  251. pop eax
  252. mov [ebx], eax
  253. jmp _next_routine
  254. PEEK4: dd _enter_native
  255. pop ebx
  256. mov eax, [ebx]
  257. push eax
  258. jmp _next_routine
  259. POKE4ADD: dd _enter_native
  260. pop ebx
  261. pop eax
  262. add [ebx], eax
  263. jmp _next_routine
  264. POKE4SUB: dd _enter_native
  265. pop ebx
  266. pop eax
  267. sub [ebx], eax
  268. jmp _next_routine
  269. POKE1: dd _enter_native
  270. pop ebx
  271. pop eax
  272. mov [ebx], al
  273. jmp _next_routine
  274. PEEK1: dd _enter_native
  275. pop ebx
  276. xor eax, eax
  277. mov al, [ebx]
  278. push eax
  279. jmp _next_routine
  280. COPY1: dd _enter_native
  281. mov ebx, [esp+4]
  282. mov edx, [esp]
  283. mov al, [ebx]
  284. mov [edx], al
  285. inc dword [esp]
  286. inc dword [esp+4]
  287. jmp _next_routine
  288. COPY4: dd _enter_native
  289. mov ebx, [esp+4]
  290. mov edx, [esp]
  291. mov eax, [ebx]
  292. mov [edx], eax
  293. add dword [esp], 4
  294. add dword [esp+4], 4
  295. jmp _next_routine
  296. MOVE1: dd _enter_native
  297. cld
  298. pop ecx
  299. mov edx, ecx
  300. shr ecx, 2
  301. and edx, 3
  302. pop edi
  303. pop esi
  304. rep movsd
  305. mov ecx, edx
  306. rep movsb
  307. jmp _next_routine
  308. ;; Return and Data Stack's pointer control
  309. PUSHRST: dd _enter_native
  310. lea ebp, [ebp-4]
  311. pop eax
  312. mov [ebp], eax
  313. jmp _next_routine
  314. POPRST: dd _enter_native
  315. push dword [ebp]
  316. lea ebp, [ebp+4]
  317. jmp _next_routine
  318. RSTFETCH: dd _enter_native
  319. push ebp
  320. jmp _next_routine
  321. RSTSTORE: dd _enter_native
  322. pop ebp
  323. jmp _next_routine
  324. RSTDROP: dd _enter_native
  325. lea ebp, [ebp+4]
  326. jmp _next_routine
  327. DSTFETCH: dd _enter_native
  328. mov eax, esp
  329. push eax
  330. jmp _next_routine
  331. DSTSTORE: dd _enter_native
  332. pop esp
  333. jmp _next_routine
  334. ;; Input/Output
  335. KEY: dd _enter_native
  336. call _KEY
  337. push eax
  338. jmp _next_routine
  339. _KEY:
  340. save_reg ebx,ecx,edx
  341. .start:
  342. movzx ebx, [read.cursor]
  343. movzx ecx, [read.top]
  344. cmp ebx, ecx
  345. jge .read_more
  346. movzx eax, byte [read.buffer+ebx]
  347. inc [read.cursor]
  348. restore_reg ebx,ecx,edx
  349. ret
  350. .read_more:
  351. mov eax, sys_read
  352. mov ebx, STDIN
  353. mov ecx, read.buffer
  354. mov edx, 4096
  355. int 80h
  356. test eax, eax
  357. jbe .read_error
  358. mov [read.top], ax
  359. mov [read.cursor], 0
  360. jmp _KEY.start
  361. .read_error:
  362. mov eax, -1
  363. restore_reg ebx,ecx,edx
  364. ret
  365. EMIT: dd _enter_native
  366. pop eax
  367. call _EMIT
  368. jmp _next_routine
  369. _EMIT:
  370. save_reg ebx,ecx,edx
  371. push eax
  372. mov ebx, STDOUT
  373. mov ecx, esp
  374. mov edx, 1
  375. mov eax, sys_write
  376. int 80h
  377. pop eax
  378. restore_reg ebx,ecx,edx
  379. ret
  380. WORD1: dd _enter_native
  381. call _WORD
  382. push word_buffer
  383. push ecx
  384. jmp _next_routine
  385. _WORD:
  386. save_reg edi,eax
  387. .start:
  388. mov edi, word_buffer
  389. mov ecx, 31
  390. .read_first:
  391. call _KEY
  392. cmp eax, -1
  393. je .error
  394. cmp al, '\'
  395. je .skip_comment
  396. cmp al, ' '
  397. je .read_first
  398. cmp al, 10
  399. je .read_first
  400. stosb
  401. .read_next:
  402. call _KEY
  403. cmp eax, -1
  404. je .error
  405. cmp al, '\'
  406. je .skip_comment
  407. cmp al, ' '
  408. je .end
  409. cmp al, 10
  410. je .end
  411. stosb
  412. loop .read_next
  413. .end:
  414. neg ecx
  415. add ecx, 32
  416. restore_reg edi,eax
  417. ret
  418. .error:
  419. mov ecx, -1
  420. restore_reg edi,eax
  421. ret
  422. .skip_comment:
  423. call _KEY
  424. cmp eax, -1
  425. je .error
  426. cmp al, 10
  427. jne .skip_comment
  428. jmp .end
  429. WRITE1: dd _enter_native
  430. save_reg eax,ebx,ecx,edx
  431. pop edx ecx
  432. test edx, edx
  433. js @f
  434. jz @f
  435. mov ebx, STDOUT
  436. mov eax, sys_write
  437. int 80h
  438. @@:
  439. restore_reg eax,ebx,ecx,edx
  440. jmp _next_routine
  441. ;@-leo