APROFILE.ASM 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. ;
  2. ; Command & Conquer Red Alert(tm)
  3. ; Copyright 2025 Electronic Arts Inc.
  4. ;
  5. ; This program is free software: you can redistribute it and/or modify
  6. ; it under the terms of the GNU General Public License as published by
  7. ; the Free Software Foundation, either version 3 of the License, or
  8. ; (at your option) any later version.
  9. ;
  10. ; This program is distributed in the hope that it will be useful,
  11. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ; GNU General Public License for more details.
  14. ;
  15. ; You should have received a copy of the GNU General Public License
  16. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ;
  18. ;***************************************************************************
  19. ;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
  20. ;***************************************************************************
  21. ;* *
  22. ;* Project Name : Profiler *
  23. ;* *
  24. ;* File Name : APROFILE.ASM *
  25. ;* *
  26. ;* Programmer : Steve Tall *
  27. ;* *
  28. ;* Start Date : November 17th, 1995 *
  29. ;* *
  30. ;* Last Update : November 20th, 1995 [ST] *
  31. ;* *
  32. ;*-------------------------------------------------------------------------*
  33. ;* Functions: *
  34. ;* __PRO -- must be called at the beginning of each function *
  35. ;* __EPI -- must be called at the end of each function *
  36. ;* Copy_CHL -- initialise the profiler asm data *
  37. ;* Profiler_Callback -- windows callback for millisecond timer *
  38. ;* *
  39. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  40. p386
  41. model flat
  42. ideal
  43. jumps
  44. MAX_PROFILE_TIME = 60*1 ;1 minute(s)
  45. PROFILE_RATE = 1000 ;1000 samples per sec
  46. ;
  47. ; Externs
  48. ;
  49. ;
  50. global C ProfileFunctionAddress:dword
  51. global C ProfilePtr:dword
  52. global C ProfileList:dword
  53. global C Stop_Profiler:near
  54. global New_Profiler_Callback_:near
  55. global Old_Profiler_Callback_:near
  56. global C Profile_Init:near
  57. global C Profile_End:near
  58. global ___begtext:near
  59. global BaseAddress:dword
  60. global __PRO:near
  61. global __EPI:near
  62. global MyStack:dword
  63. global MyStackPtr:dword
  64. global ProAddress:dword
  65. global EpiAddress:dword
  66. codeseg
  67. ;*********************************************************************************************
  68. ;* __PRO -- registers the current procedure *
  69. ;* *
  70. ;* INPUT: Nothing *
  71. ;* *
  72. ;* OUTPUT: none *
  73. ;* *
  74. ;* Warnings: *
  75. ;* Assumes that ss:Esp points to return address in function to be registered *
  76. ;* *
  77. ;* HISTORY: *
  78. ;* 11/20/95 4:39PM ST : Created. *
  79. ;*===========================================================================================*
  80. proc __PRO near
  81. jmp [ProAddress]
  82. ; safe version of prologue code
  83. Pro_Start: push eax
  84. mov eax,[MyStackPtr]
  85. push [ProfileFunctionAddress]
  86. pop [eax*4+MyStack]
  87. inc [MyStackPtr]
  88. pop eax
  89. push [dword ss:esp]
  90. pop [ProfileFunctionAddress]
  91. Pro_End: ret
  92. ; unsafe (but much faster) prologue code
  93. ; pop [ProfileFunctionAddress]
  94. ; jmp [ProfileFunctionAddress]
  95. endp __PRO
  96. ;*********************************************************************************************
  97. ;* __EPI -- Registers the privious procedure as current again *
  98. ;* *
  99. ;* INPUT: Nothing *
  100. ;* *
  101. ;* OUTPUT: none *
  102. ;* *
  103. ;* Warnings: *
  104. ;* Assumes that calling procedure will pop ebp immediately on return so we dont have to *
  105. ;* preserve it. *
  106. ;* *
  107. ;* HISTORY: *
  108. ;* 11/20/95 4:42PM ST : Created. *
  109. ;*===========================================================================================*
  110. proc __EPI near
  111. jmp [EpiAddress]
  112. ; Safe version of epilogue code. Uncomment the push and pop for ultimate safety
  113. Epi_Start: dec [MyStackPtr]
  114. ; push ebp
  115. mov ebp,[MyStackPtr]
  116. mov ebp,[ebp*4+MyStack]
  117. mov [ProfileFunctionAddress],ebp
  118. ; pop ebp
  119. Epi_End: ret
  120. ; Unsafe (but much faster) epilogue code. Makes lots of assumptions.
  121. ; push [dword esp+8]
  122. ; pop [ProfileFunctionAddress]
  123. ; ret
  124. endp __EPI
  125. ;*********************************************************************************************
  126. ;* Profile_Init -- Initialises the .asm data required for profile session *
  127. ;* *
  128. ;* INPUT: Nothing *
  129. ;* *
  130. ;* OUTPUT: none *
  131. ;* *
  132. ;* Warnings: *
  133. ;* Assumes that '___begtext' is the first label in the code segment and that its *
  134. ;* address is within 15 bytes of the start of the code segment *
  135. ;* *
  136. ;* HISTORY: *
  137. ;* 11/20/95 4:44PM ST : Created. *
  138. ;*===========================================================================================*
  139. proc Profile_Init C near
  140. mov eax,offset ___begtext
  141. and eax,0fffffff0h
  142. mov [BaseAddress],eax
  143. ;mov [MyStackPtr],0
  144. mov [ProfileList],PROFILE_RATE
  145. mov [ProfilePtr],1
  146. mov [ProAddress],offset Pro_Start
  147. mov [EpiAddress],offset Epi_Start
  148. ret
  149. endp Profile_Init
  150. ;*********************************************************************************************
  151. ;* Profile_End -- disables the __PRO and __EPI procedures *
  152. ;* *
  153. ;* INPUT: Nothing *
  154. ;* *
  155. ;* OUTPUT: none *
  156. ;* *
  157. ;* Warnings: *
  158. ;* *
  159. ;* HISTORY: *
  160. ;* 11/20/95 4:44PM ST : Created. *
  161. ;*===========================================================================================*
  162. proc Profile_End C near
  163. mov [ProAddress],offset Pro_End
  164. mov [EpiAddress],offset Epi_End
  165. ret
  166. endp Profile_End
  167. ;*********************************************************************************************
  168. ;* New_Profiler_Callback -- Windows callback used to register function hits *
  169. ;* *
  170. ;* INPUT: Nothing *
  171. ;* *
  172. ;* OUTPUT: none *
  173. ;* *
  174. ;* Note: *
  175. ;* The frequency that this is called depends on MAX_PROFILE_RATE defined here and in *
  176. ;* profile.h *
  177. ;* *
  178. ;* HISTORY: *
  179. ;* 11/20/95 4:47PM ST : Created. *
  180. ;*===========================================================================================*
  181. proc New_Profiler_Callback_ near
  182. push eax
  183. push esi
  184. mov esi,[ProfilePtr]
  185. cmp esi,MAX_PROFILE_TIME*PROFILE_RATE
  186. jge @@out
  187. mov eax,[ProfileFunctionAddress]
  188. sub eax,[BaseAddress]
  189. mov [ProfileList+esi*4],eax
  190. inc [ProfilePtr]
  191. pop esi
  192. pop eax
  193. ret
  194. @@out: call Stop_Profiler
  195. pop esi
  196. pop eax
  197. ret
  198. endp New_Profiler_Callback_
  199. ;*********************************************************************************************
  200. ;* Old_Profiler_Callback -- Windows callback used to register function hits *
  201. ;* *
  202. ;* INPUT: Windows timer callback stuff - not used *
  203. ;* *
  204. ;* OUTPUT: none *
  205. ;* *
  206. ;* Note: *
  207. ;* The frequency that this is called depends on MAX_PROFILE_RATE defined here and in *
  208. ;* profile.h *
  209. ;* *
  210. ;* HISTORY: *
  211. ;* 11/20/95 4:47PM ST : Created. *
  212. ;*===========================================================================================*
  213. proc Old_Profiler_Callback_ near
  214. push eax
  215. push esi
  216. mov esi,[ProfilePtr]
  217. cmp esi,MAX_PROFILE_TIME*PROFILE_RATE
  218. jge @@out
  219. mov eax,[ProfileFunctionAddress]
  220. sub eax,[BaseAddress]
  221. mov [ProfileList+esi*4],eax
  222. inc [ProfilePtr]
  223. pop esi
  224. pop eax
  225. ret 14h
  226. @@out: call Stop_Profiler
  227. pop esi
  228. pop eax
  229. ret 14h
  230. endp Old_Profiler_Callback_
  231. dataseg
  232. align 4
  233. ProfileFunctionAddress dd 0 ;Ptr to function we are currently in
  234. BaseAddress dd 0 ;Address of the code segment start
  235. MyStackPtr dd 0 ;offset into my stack table
  236. ProAddress dd Pro_Start ;jmp ptr for __PRO procedure
  237. EpiAddress dd Epi_Start ;jmp ptr for __EPI procedure
  238. label MyStack dword ;my stack table
  239. dd 16*1024 dup (?)
  240. end