Source code of Windows XP (NT5)
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.

449 lines
13 KiB

  1. ;++
  2. ;
  3. ; Copyright (c) 1991 Microsoft Corporation
  4. ;
  5. ; Module Name:
  6. ;
  7. ; ntnap.asm
  8. ;
  9. ; Abstract:
  10. ;
  11. ; This module implements the system service dispatch procedure.
  12. ; It also creates a "profile" of each service by counting and
  13. ; timing calls.
  14. ;
  15. ; Author:
  16. ;
  17. ; Russ Blake (russbl) 22-Apr-1991
  18. ;
  19. ; Environment:
  20. ;
  21. ; User or kernel mode.
  22. ;
  23. ; Revision History:
  24. ;
  25. ;--
  26. include ks386.inc
  27. include callconv.inc ; calling convention macros
  28. include mac386.inc
  29. include ntnap.inc
  30. .386
  31. EXTRN _NapDllInit:near
  32. EXTRN _NapRecordInfo:near
  33. NapStart equ [ebp - 08h]
  34. NapEnd equ [ebp - 010h]
  35. NapServiceNum equ [ebp - 014h]
  36. NapLocalSize equ 4 * 5
  37. NapCalSrvNum equ 0FFFFFFFFh
  38. ;++
  39. ;
  40. ; Routine Description:
  41. ;
  42. ; This routine is called to save registers during API profiling.
  43. ; The objecttive is to preserve the caller's environment
  44. ; while timing takes place and, once, while dll initialization
  45. ; takes place. This routine svaes registers on the stack to
  46. ; permit recursivce calls.
  47. ;
  48. ; There should be a matching call to NapRestoreRegs to restore
  49. ; the registers.
  50. ;
  51. ; Arguments:
  52. ;
  53. ; All registers.
  54. ;
  55. ; Return Value:
  56. ;
  57. ; None. All registers are preserved on the stack.
  58. ;
  59. ;--
  60. .386p
  61. _TEXT SEGMENT DWORD USE32 PUBLIC 'CODE'
  62. ASSUME CS:FLAT, DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  63. cPublicProc _NapSaveRegs
  64. ;
  65. ; This is how the stack looks like upon entering this routine:
  66. ;
  67. ; ---+----+----+----+----+----
  68. ; | Return Address |
  69. ; ---+----+----+----+----+----
  70. ; esp+ esp+
  71. ; 0 4
  72. ;
  73. ;
  74. ; -> popping makes esp go ->
  75. ; <- pushing makes esp go <-
  76. ;
  77. push ebp
  78. mov ebp,esp ; Remember where we are during this stuff
  79. ; ebp = Original esp - 4
  80. push eax
  81. push ebx
  82. push ecx
  83. push edx
  84. push esi
  85. push edi
  86. pushfd
  87. push ds
  88. push es
  89. push ss
  90. push fs
  91. push gs
  92. mov eax,[ebp+4] ; Grab Return Address
  93. push eax ; Put Return Address on Stack
  94. mov ebp,[ebp+0] ; Restore original ebp
  95. ;
  96. ; This is how the stack looks like just before executing RET:
  97. ;
  98. ;
  99. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  100. ; | Return Address | g s | f s |
  101. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  102. ; esp+
  103. ; 0
  104. ;
  105. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  106. ; | s s | e s | d s |
  107. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  108. ; esp+
  109. ; c
  110. ;
  111. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  112. ; | eflags | edi | esi |
  113. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  114. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  115. ; | edx | ecx | ebx |
  116. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  117. ; +----+----+----+----+----+----+----+----+----+----+----+----+----
  118. ; | eax | original ebp | Return Address |
  119. ; +----+----+----+----+----+----+----+----+----+----+----+----+----
  120. ; was
  121. ; ebp+
  122. ; 0
  123. ;
  124. stdRET _NapSaveRegs
  125. stdENDP _NapSaveRegs
  126. cPublicProc _NapRestoreRegs,,near
  127. ;
  128. ; This is how the stack looks like upon entering this routine:
  129. ;
  130. ;
  131. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  132. ; | Return Address | g s | f s |
  133. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  134. ; esp+
  135. ; 0
  136. ;
  137. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  138. ; | s s | e s | d s |
  139. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  140. ; esp+
  141. ; c
  142. ;
  143. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  144. ; | eflags | edi | esi |
  145. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  146. ; esp+
  147. ; 18
  148. ;
  149. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  150. ; | edx | ecx | ebx |
  151. ; +----+----+----+----+----+----+----+----+----+----+----+----+
  152. ; esp+
  153. ; 24
  154. ;
  155. ; +----+----+----+----+----+----+----+----+----+----+----+----+----
  156. ; | eax | original ebp | Return Address |
  157. ; +----+----+----+----+----+----+----+----+----+----+----+----+----
  158. ; esp+ esp+ esp+
  159. ; 30 34 38
  160. ;
  161. pop eax ; Get Return Address
  162. push ebp ; Save a temporary copy of original BP
  163. mov ebp,esp ; BP = Original SP + 4
  164. mov [ebp+038h],eax ; Put Return Address on Stack
  165. pop eax ; Get Original BP
  166. mov [ebp+034h],eax ; Put it in the original BP place
  167. pop gs
  168. pop fs
  169. pop ss
  170. pop es
  171. pop ds
  172. popfd
  173. pop edi
  174. pop esi
  175. pop edx
  176. pop ecx
  177. pop ebx
  178. pop eax
  179. pop ebp
  180. stdRET _NapRestoreRegs
  181. stdENDP _NapRestoreRegs
  182. ;++
  183. ;
  184. ; Routine Description:
  185. ;
  186. ; This routine is called by the initialization code in the
  187. ; Nt Api Profiler to calibrate the cost of profiling.
  188. ; It simulates the overhead of a profiled call to a system
  189. ; service, but carefully avoids doing any of the normal
  190. ; work associated with such a call.
  191. ;
  192. ; NOTE: This routine's code should exactly parallel that of
  193. ; _NapDispatch, except for any operation normally
  194. ; (i.e., when not profiling) executed to call a system service.
  195. ; This amounts to an "int 2Eh" in the middle of the routine.
  196. ;
  197. ; Arguments:
  198. ;
  199. ; eax - Service Number of the routine being called. Must be -1
  200. ; for all calls to this routine. The routine
  201. ; _NapRecordInfo notes this value and discards
  202. ; the call.
  203. ;
  204. ; edx - Pointer to the parameters to the Service; ignored by
  205. ; this routine.
  206. ;
  207. ; Return Value:
  208. ;
  209. ; None.
  210. ;
  211. ;--
  212. cPublicProc _NapCalibrate , ,near
  213. push ebp ; Locals: the value of
  214. mov ebp, esp ; the perf counter before and
  215. sub esp, NapLocalSize ; after the API call
  216. mov eax, NapCalSrvNum ; special routine number
  217. mov NapServicenum, eax ; is used for calibration
  218. ; can't be passed in eax from
  219. ; C routine, so load it here
  220. ; save the service routine number
  221. stdCall _NapSaveRegs ; save register state so call to
  222. ; get counter does not destroy them
  223. stdCall _NapDllInit ; initialize dll if necessary
  224. ; Now call NtQueryPerformanceCounter to get the starting count;
  225. ; Store this locally
  226. push 0 ; don't need frequency: pass 0
  227. lea eax, NapStart ; (eax) = pointer to counter
  228. push eax ; pass pointer to counter
  229. mov eax, NapCounterServiceNumber
  230. lea edx, [esp] ; (edx) -> arguments
  231. int 2Eh ; get the current counter value
  232. add esp, 08h ; remove counter parameters
  233. ; Restore caller's registers
  234. stdCall _NapRestoreRegs
  235. ; We're just calibrating the overhead, so we don't call the system
  236. ; service here.
  237. ; Save regsiters so we can complete the profile accounting.
  238. stdCall _NapSaveRegs
  239. ; Now get the ending counter.
  240. push 0 ; don't need frequency: pass 0
  241. lea eax, NapEnd ; (eax) = pointer to counter
  242. push eax ; pass pointer to counter
  243. mov eax, NapCounterServiceNumber
  244. lea edx, [esp] ; (edx) -> arguments
  245. int 2Eh ; get the current counter value
  246. add esp, 08h ; remove counter parameters
  247. ; Compute the time for this call and increment the nukmber of calls.
  248. lea eax, NapEnd ; pointer to start/end counters
  249. ; ID of this routine
  250. stdCall _NapRecordInfo, <NapServiceNum, eax>
  251. stdCall _NapRestoreRegs
  252. ; restore caller's registers
  253. leave ; we needed this for pseudo locals
  254. stdRET _NapCalibrate
  255. stdENDP _NapCalibrate
  256. ;++
  257. ;
  258. ; Routine Description:
  259. ;
  260. ; This routine is called by the USRSTUBS_ENTRY1 MACRO in the
  261. ; services.prf to carry out profiling on an Nt system api call.
  262. ;
  263. ; Arguments:
  264. ;
  265. ; eax - Service Number of the routine being called. This number
  266. ; is assigned by genprof.c from the table in services.tab.
  267. ;
  268. ; edx - Pointer to the parameters to the Service.
  269. ;
  270. ; Return Value:
  271. ;
  272. ; Whatever the system service returns.
  273. ;
  274. ;--
  275. cPublicProc _NapProfileDispatch , ,near
  276. push ebp ; Locals: the value of
  277. mov ebp, esp ; the perf counter before and
  278. sub esp, NapLocalSize ; after the API call
  279. mov NapServicenum, eax
  280. ; save the service routine number
  281. stdCall _NapSaveRegs ; save register state so call to
  282. ; get counter does not destroy them
  283. stdCall _NapDllInit ; initialize dll if necessary
  284. ; Now call NtQueryPerformanceCounter to get the starting count;
  285. ; Store this locally
  286. push 0 ; don't need frequency: pass 0
  287. lea eax, NapStart ; (eax) = pointer to counter
  288. push eax ; pass pointer to counter
  289. mov eax, NapCounterServiceNumber
  290. lea edx, [esp] ; (edx) -> arguments
  291. int 2Eh ; get the current counter value
  292. add esp, 08h ; remove counter parameters
  293. ; Restore caller's registers
  294. stdCall _NapRestoreRegs
  295. INT 2Eh ; invoke system service
  296. ; Save regsiters so we can complete the profile accounting.
  297. stdCall _NapSaveRegs
  298. ; Now get the ending counter.
  299. push 0 ; don't need frequency: pass 0
  300. lea eax, NapEnd ; (eax) = pointer to counter
  301. push eax ; pass pointer to counter
  302. mov eax, NapCounterServiceNumber
  303. lea edx, [esp] ; (edx) -> arguments
  304. int 2Eh ; get the current counter value
  305. add esp, 08h ; remove counter parameters
  306. ; Compute the time for this call and increment the number of calls.
  307. lea eax, NapEnd ; pointer to start/end counters
  308. ; ID of this routine
  309. stdCall _NapRecordInfo, <NapServiceNum, eax>
  310. stdCall _NapRestoreRegs
  311. ; restore caller's registers
  312. leave ; we needed this for pseudo locals
  313. stdRET _NapProfileDispatch
  314. stdENDP _NapProfileDispatch
  315. ;++
  316. ;
  317. ; Routine Description:
  318. ;
  319. ; This routine is claled to get the spin lock associated with
  320. ; a particular api. It prevents the simultaneous update
  321. ; from multiple threads in this or other processors of the
  322. ; profiling data for the api.
  323. ;
  324. ; Arguments:
  325. ;
  326. ; SpinLockAddr - address of the spin lock within the data
  327. ; for the api being updated.
  328. ;
  329. ; Return Value:
  330. ;
  331. ; None.
  332. ;
  333. ;--
  334. cPublicProc _NapAcquireSpinLock , ,near
  335. push eax
  336. mov eax, [esp+8] ; get address of lock
  337. WaitForLock:
  338. lock bts dword ptr [eax], 0 ; test and set the spinlock
  339. jc SHORT WaitForLock ; spinlock owned: go to SpinLabel
  340. pop eax
  341. stdRET _NapAcquireSpinLock
  342. stdENDP _NapAcquireSpinLock
  343. ;++
  344. ;
  345. ; Routine Description:
  346. ;
  347. ; This routine is called to release the spin lock associated with
  348. ; a particular api.
  349. ;
  350. ; Arguments:
  351. ;
  352. ; SpinLockAddr - address of the spin lock within the data
  353. ; for the api being updated.
  354. ;
  355. ; Return Value:
  356. ;
  357. ; None.
  358. ;
  359. ;--
  360. cPublicProc _NapReleaseSpinLock , ,near
  361. push eax
  362. mov eax, [esp+8] ; get address of lock
  363. lock btr dword ptr [eax], 0 ; release spinlock
  364. pop eax
  365. stdRET _NapReleaseSpinLock
  366. stdENDP _NapReleaseSpinLock
  367. _TEXT ends
  368. end