proc32.inc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. ; Macroinstructions for defining and calling procedures
  2. macro locals {
  3. local ..locsize
  4. locsize equ ..locsize
  5. virtual at ebp - ..locsize - .__info.commonframe.size
  6. @@:
  7. }
  8. macro endl {
  9. rb (4 - ($- @b) and 11b) and 11b
  10. locsize = $ - @b
  11. if $-@b > maxsize
  12. maxsize = $-@b
  13. end if
  14. end virtual
  15. restore locsize
  16. }
  17. macro err@endp { }
  18. macro proc2 name, [arg] {
  19. common
  20. err@endp
  21. macro err@endp \{
  22. end if
  23. Missing 'endp' before the procedure.
  24. \}
  25. if defined options.AlignCode & options.AlignCode
  26. align 16
  27. end if
  28. name:
  29. .__info.id = 1
  30. .__info.start = $
  31. virtual at ebp+8
  32. if ~ arg eq
  33. forward
  34. arg dd ?
  35. if ~ defined name#arg
  36. ERROR! the argument `arg MUST begins with dot
  37. end if
  38. common
  39. end if
  40. .__info.argsize = $-ebp-8
  41. end virtual
  42. if ~ used name
  43. if defined options.ShowSkipped & options.ShowSkipped
  44. display 1,'Procedure skipped: ',`name, $0d, $0a
  45. end if
  46. else
  47. virtual at ebp - .__info.commonframe.size
  48. .__info.commonframe.begin:
  49. }
  50. macro doas name1, name2, [arg] {
  51. common
  52. proc2 name1, arg
  53. }
  54. macro proc name, [arg] {
  55. common
  56. local ..norm
  57. define ..norm TRUE
  58. match pname as iface, name \{
  59. define ..norm FALSE
  60. if ~defined interfaces.\#iface
  61. ERROR! Not defined \`iface interface.
  62. end if
  63. match interface, interface@\#iface \\{
  64. doas pname, interface
  65. \\}
  66. \}
  67. match =TRUE, ..norm \{
  68. proc2 name, arg
  69. \}
  70. }
  71. macro begin {
  72. rb (4 - ($ - .__info.commonframe.begin) and 11b) and 11b
  73. .__info.commonframe.size = $ - .__info.commonframe.begin
  74. end virtual
  75. local ..maxsize
  76. maxsize equ ..maxsize
  77. ..maxsize = 0
  78. if .__info.framesize
  79. if defined options.FastEnter & options.FastEnter
  80. push ebp
  81. mov ebp, esp
  82. sub esp, .__info.framesize
  83. else
  84. enter .__info.framesize, 0
  85. end if
  86. else
  87. if .__info.argsize
  88. push ebp
  89. mov ebp, esp
  90. end if
  91. end if
  92. }
  93. macro cret {
  94. if .__info.argsize | .__info.framesize
  95. if defined options.FastEnter & options.FastEnter
  96. mov esp, ebp
  97. pop ebp
  98. else
  99. leave
  100. end if
  101. end if
  102. retn
  103. }
  104. macro return {
  105. if .__info.argsize | .__info.framesize
  106. if defined options.FastEnter & options.FastEnter
  107. mov esp, ebp
  108. pop ebp
  109. else
  110. leave
  111. end if
  112. end if
  113. if .__info.argsize
  114. retn .__info.argsize
  115. else
  116. retn
  117. end if
  118. }
  119. macro endp {
  120. .__info.framesize = maxsize + .__info.commonframe.size
  121. .__info.codesize = $ - .__info.start
  122. end if
  123. restore maxsize
  124. purge err@endp
  125. }
  126. ; Defines procedure interface, separate from the procedure body. Useful for
  127. ; portable libraries, where the body is an OS dependent, but the interface should not.
  128. ; Must be defined prior to the "body" definition.
  129. macro interface name, [arg] {
  130. common
  131. \interface@#name equ name, arg
  132. interfaces.#name = 1
  133. }
  134. ; Defines procedure body, for already defined interface.
  135. macro body name {
  136. if ~defined interfaces.#name
  137. ERROR! Not defined interface for `name procedure.
  138. end if
  139. match interface, interface@#name \{ proc interface \}
  140. }
  141. macro event name, [arg] {
  142. common
  143. name dd ?
  144. interfaces.#name = 1
  145. interface@#name equ name
  146. forward
  147. match var, interface@#name \{ \interface@#name equ var, .#arg \}
  148. }
  149. ;*****************************************
  150. ; Call macroses
  151. ;*****************************************
  152. macro pushx [arg] {
  153. common
  154. local f1, f2, cnt, sz
  155. cnt = 0
  156. sz = 0
  157. f1 = 1
  158. f2 equ FALSE
  159. forward
  160. match any, arg \{
  161. match `arg, arg \\{ f2 equ TRUE \\}
  162. \}
  163. cnt = cnt + 1
  164. if arg eqtype ''
  165. virtual at 0
  166. db arg
  167. sz = sz + $
  168. end virtual
  169. end if
  170. common
  171. local lbl
  172. match =txt string, arg \{
  173. f1 = 0
  174. lbl text string
  175. f2 equ FALSE
  176. \}
  177. if (sz > 4) | (cnt>1)
  178. f1 = 0
  179. end if
  180. if f1
  181. pushd arg
  182. else
  183. pushd lbl
  184. end if
  185. match =TRUE, f2 \{ lbl text arg \}
  186. }
  187. macro stdcall proc, [arg] { ; call procedure
  188. common
  189. local ..argsize
  190. ..argsize = 0
  191. if ~ arg eq
  192. reverse
  193. pushx arg
  194. ..argsize = ..argsize + 4
  195. common
  196. end if
  197. if defined options.CheckArguments & options.CheckArguments
  198. if (defined proc#.__info.argsize) & (proc#.__info.argsize <> ..argsize)
  199. ERROR! wrong argument count for procedure call.
  200. end if
  201. end if
  202. call proc
  203. }
  204. macro invoke proc,[arg] { ; invoke procedure (indirect)
  205. common
  206. if ~ arg eq
  207. reverse
  208. pushx arg
  209. common
  210. end if
  211. call [proc]
  212. }
  213. macro ccall proc,[arg] { ; call procedure in C calling convention
  214. common local ..size
  215. ..size = 0
  216. reverse
  217. pushx arg
  218. ..size = ..size+4
  219. common
  220. call proc
  221. if defined proc#.__info.argsize
  222. if proc#.__info.argsize > 0
  223. add esp, proc#.__info.argsize
  224. end if
  225. else
  226. if ..size > 0
  227. add esp,..size
  228. end if
  229. end if
  230. }
  231. macro cinvoke proc, [arg] { ; invoke procedure (indirect)
  232. common local ..size
  233. ..size = 0
  234. if ~ arg eq
  235. reverse
  236. pushx arg
  237. ..size = ..size+4
  238. common
  239. end if
  240. call [proc]
  241. if defined proc#.__info.argsize
  242. if proc#.__info.argsize > 0
  243. add esp, proc#.__info.argsize
  244. end if
  245. else
  246. if ..size > 0
  247. add esp, ..size
  248. end if
  249. end if
  250. }
  251. ;****************************************
  252. ; INT3 break point, when first = second.
  253. ;****************************************
  254. macro BreakEq first, second {
  255. local .lbl
  256. push eax
  257. mov eax, first
  258. cmp eax, second
  259. pop eax
  260. jne .lbl
  261. int3
  262. .lbl:
  263. }