Leaked source code of windows server 2003
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.

778 lines
21 KiB

  1. ;***
  2. ;cruntime.inc - multi-model assembly macros for interfacing to HLLs
  3. ;
  4. ; Copyright (c) 1988-1995, Microsoft Corporation. All rights reserved.
  5. ;
  6. ;Purpose:
  7. ; This file defines the current memory model being used.
  8. ;
  9. ;*******************************************************************************
  10. ;==============================================================================
  11. ;
  12. ;Use the following defines to control processor/segment model
  13. ;
  14. ; -DI86 8086/8088 processor
  15. ; -DI286 80286 processor
  16. ; -DI386 80386 processor with 32-bit code/data segment
  17. ;
  18. ; -Dmem_S Small memory model (near code, near data)
  19. ; -Dmem_M Medium memory model (far code, near data)
  20. ; -Dmem_C Compact memory model (near code, fat data)
  21. ; -Dmem_L Large memory model (far code, far data)
  22. ;
  23. ; -DSS_NEQ_DGROUP SS and DS point to different segments
  24. ;
  25. ; default is -DI86 -Dmem_S
  26. ;
  27. ;==============================================================================
  28. ;
  29. ;The following variables are defined by this file:
  30. ; cpu 86, 286, or 386
  31. ; sizeC code distance; 1 = far code, 0 = near code
  32. ; sizeD data distance; 1 = far data, 0 = near data
  33. ; mmodel english name of the memory model, i.e. "Medium"
  34. ; ISIZE, LSIZE, NSIZE size of ints, longs, shorts
  35. ; FLTSIZE, DBLSIZE, LDBLSIZE size of float, double, long double
  36. ; NPSIZE, FPSIZE size of near/far pointers
  37. ; CPSIZE, DPSIZE size of code/data pointers
  38. ; ISHIFT, LSHIFT bits to shift to convert byte to int/long
  39. ;
  40. ;The following macros allow easy writing of combined 16/32 bit code:
  41. ;
  42. ; 16/32 bit registers:
  43. ; rax, rbx, rcx, rdx, expand to native registers (rax = eax or ax)
  44. ; rsi, rdi, rsp, rbp
  45. ; 16/32 bit register instructions:
  46. ; JRCXZ jump when rcx is zero
  47. ; CBI convert byte to int (al to rax)
  48. ; CAXDX convert rax to rax:rdx
  49. ; ZXAL, ZXBL, ZXCL, ZXDL zero extend al,bl,cl,dl to rax,rbx,rcx,rdx
  50. ; Pointer instructions:
  51. ; LPDS, LPES load data pointer with ES or DS
  52. ; PDS, PES segment overrides when pointer loaded as above
  53. ; PCS, PSS segment override to get at code/stack segment
  54. ; LFPDS, LFPES load far pointer with ES or DS
  55. ; FPDS, FPES segment overrides when pointer loaded as above
  56. ; CPTR data type of code pointer
  57. ; CPDIST distance of code (near/far)
  58. ; DNPTR, DFPTR define near/far pointer
  59. ; DCPTR, DDPTR define code/data pointer
  60. ; DCPTR?, DDPTR? define uninitialized code/data pointer
  61. ; CPWORD, DPWORD data type of code or data pointer
  62. ; Numeric type instructions:
  63. ; IWORD, LWORD, SWORD data type of int, long, short
  64. ; DINT, DLONG, DSHORT define int, long, short
  65. ; DFLOAT, DDOUBLE, DLDOUBLE define float, double, long double
  66. ; Offsets:
  67. ; codeoffset, dataoffset offsets from code and data segments
  68. ; API calls:
  69. ; APIDIST distance of API calls (near/far)
  70. ; APIEXT ApiName extrn declaration for an API function
  71. ;
  72. ;The following utility macros are provided:
  73. ; codeseg define/declare code segment
  74. ; error <msg> stop assembly with message
  75. ; display <msg> display a message, unless QUIET defined
  76. ; savelist [<reg> ...] init list of regs to be save by 'proc uses'
  77. ; _if cond <instruction> assemble instruction only if cond is TRUE
  78. ; _ife cond <instruction> assemble instruction only if cond is FALSE
  79. ; _ifd symbol <instruction> assemble instruction only if symbol defined
  80. ; _ifnd symbol <instruction> assemble instruction only if symbol not defined
  81. ;
  82. ; lab LabelName assembles to "LabelName:" If DEBUG is defined
  83. ; LabelName is made public
  84. ;
  85. ; JS* (ex. JSE,JSZ,JSB ...) assemble to "je short","jz short","jb short"
  86. ;
  87. ; Cmacro look alikes
  88. ; static* Name, InitialValue, Repeat defines a static variable of type *
  89. ; global* Name, InitialValue, Repeat defines a global variable of type *
  90. ; label* Name, {PUBLIC,PASCAL,C} defines a label of type *
  91. ;
  92. ; PUSH16 SegmentReg pushes 16 bits in a use32 segment
  93. ; JMPFAR16 label will do a far 16:16 jmp from a use32 segment
  94. ;
  95. ;==============================================================================
  96. ; error <msg> - Output message and generate error
  97. error MACRO msg
  98. if2 ;; only on pass 2 can we generate errors
  99. %out **********************************************************
  100. %out *** E r r o r -- msg
  101. %out **********************************************************
  102. .err
  103. endif
  104. ENDM
  105. ; display msg - Output message unless QUIET defined
  106. display MACRO msg
  107. ifndef QUIET ;; only when quiet flag not set
  108. if1 ;; and on pass 1, then display message
  109. %out msg
  110. endif
  111. endif
  112. ENDM
  113. ; One line conditionals:
  114. ; here we create the capability of writing code lines like
  115. ;
  116. ; _if sizeD <push ds> as opposed to if sizeD
  117. ; push ds
  118. ; endif
  119. _if MACRO cond,text
  120. if cond
  121. text
  122. endif
  123. ENDM
  124. _ife MACRO cond,text
  125. ife cond
  126. text
  127. endif
  128. ENDM
  129. _ifd MACRO cond,text
  130. ifdef cond
  131. text
  132. endif
  133. ENDM
  134. _ifnd MACRO cond,text
  135. ifndef cond
  136. text
  137. endif
  138. ENDM
  139. ; set windows flag to 0
  140. ?WIN equ 0 ; disable windows-specific code
  141. ; check for _MT, requires 286 or greater processor
  142. ifdef _MT
  143. ifndef I386
  144. ifndef I286
  145. ; _MT implies 286 processor
  146. display <Multi-thread specified - assuming 80286 processor>
  147. I286 equ <>
  148. endif
  149. endif
  150. endif
  151. ; Process memory-model arguments
  152. ifdef mem_M
  153. ; Medium model
  154. sizeC equ 1
  155. sizeD equ 0
  156. mmodel equ <Medium>
  157. elseifdef mem_C
  158. ; Compact model
  159. sizeC equ 0
  160. sizeD equ 1
  161. mmodel equ <Compact>
  162. elseifdef mem_L
  163. ; Large model
  164. sizeC equ 1
  165. sizeD equ 1
  166. mmodel equ <Large>
  167. else
  168. ; Small model - default
  169. sizeC equ 0
  170. sizeD equ 0
  171. mmodel equ <Small>
  172. endif
  173. ; Process processor arguments
  174. ifdef _WIN32
  175. display <Processor: 486/586>
  176. cpu equ 586
  177. .586
  178. elseifdef I286
  179. display <Processor: 80286>
  180. cpu equ 286
  181. .286
  182. elseifdef I386
  183. display <Processor: 80386>
  184. cpu equ 386
  185. .386
  186. else
  187. display <Processor: 8086/8088>
  188. cpu equ 86
  189. .8086
  190. endif
  191. ; 386 32-bit checking. Currently we are only expecting small model
  192. ; 32 bit segments, so we make a few checks to be sure nothing is
  193. ; incorrectly being defined.
  194. ifdef I386
  195. if sizeC or sizeD
  196. error <Must use Small memory model for 386 version.>
  197. endif
  198. ifdef _LOAD_DGROUP
  199. error <No loading DGROUP in 386 version.>
  200. endif
  201. ifdef SS_NEQ_DGROUP
  202. error <SS always equals DGROUP in 386 version.>
  203. endif
  204. endif
  205. ; Set memory model
  206. % display <Memory model: mmodel>
  207. % .model mmodel, C
  208. ;
  209. ; *** Temporary Workaround ***
  210. ; Currently, MASM will not recognize the 'FLAT' keyword unless it previously
  211. ; appears in an 'assume' statement. Presumably, when the '.model FLAT' feature
  212. ; is implemented, this will go away. [Use 'gs:' since we never use that
  213. ; segment register.
  214. ;
  215. ifdef I386
  216. ; ensure that MASM recognizes 'FLAT'
  217. assume gs:FLAT
  218. endif
  219. ; Define registers:
  220. ; Instead of using the "word" registers directly, we will use a set of
  221. ; text equates. This will allow you to use the native word size instead of
  222. ; hard coded to 16 bit words. We also have some instruction equates for
  223. ; instruction with the register type hard coded in.
  224. ifdef I386
  225. rax equ <eax>
  226. rbx equ <ebx>
  227. rcx equ <ecx>
  228. rdx equ <edx>
  229. rdi equ <edi>
  230. rsi equ <esi>
  231. rbp equ <ebp>
  232. rsp equ <esp>
  233. JRCXZ equ <jecxz>
  234. CBI equ <movsx eax, al> ; convert byte to int (al to rax)
  235. CAXDX equ <cdq> ; convert rax to rdx:rax
  236. ZXAL equ <movzx eax, al> ; zero extend al
  237. ZXBL equ <movzx ebx, bl> ; zero extend bl
  238. ZXCL equ <movzx ecx, cl> ; zero extend cl
  239. ZXDL equ <movzx edx, dl> ; zero extend dl
  240. else
  241. rax equ <ax>
  242. rbx equ <bx>
  243. rcx equ <cx>
  244. rdx equ <dx>
  245. rdi equ <di>
  246. rsi equ <si>
  247. rbp equ <bp>
  248. rsp equ <sp>
  249. JRCXZ equ <jcxz>
  250. CBI equ <cbw> ; convert byte to int (al to rax)
  251. CAXDX equ <cwd> ; convert rax to rdx:rax
  252. ZXAL equ <xor ah, ah> ; zero extend al
  253. ZXBL equ <xor bh, bh> ; zero extend bl
  254. ZXCL equ <xor ch, ch> ; zero extend cl
  255. ZXDL equ <xor dh, dh> ; zero extend dl
  256. endif
  257. ; The following equates deal with the differences in near versus
  258. ; far data pointers, and segment overrides.
  259. ;
  260. ; Use LPES and PES when loading a default size pointer -- it loads
  261. ; a 16-bit pointer register in 286 Small/Medium model,
  262. ; a 16-bit pointer register and 16-bit segment register in 8086/286
  263. ; Compact/Large model, and a 32-bit pointer register in 386 mode.
  264. ;
  265. ; Use LFPES and FPES when loading an always far pointer -- it loads a
  266. ; 16-bit pointer register and 16-bit segment register in 8086/286,
  267. ; all models; a 32-bit pointer register in 386 mode.
  268. if sizeD
  269. LPES equ <les>
  270. LPDS equ <lds>
  271. PDS equ <ds:>
  272. PES equ <es:>
  273. else
  274. LPES equ <mov>
  275. LPDS equ <mov>
  276. PDS equ <>
  277. PES equ <>
  278. endif
  279. ifdef I386
  280. LFPES equ <mov>
  281. LFPDS equ <mov>
  282. FPES equ <>
  283. FPDS equ <>
  284. else
  285. LFPES equ <les>
  286. LFPDS equ <lds>
  287. FPES equ <es:>
  288. FPDS equ <ds:>
  289. endif
  290. if sizeC or @WordSize eq 2
  291. PCS equ <cs:> ; large code model or non-386
  292. else
  293. IF 1 ;*** TEMP 16/32 TESTBED ***
  294. PCS equ <cs:>
  295. ELSE
  296. PCS equ <> ; 386 small code model
  297. ENDIF ;*** END TEMP CODE
  298. endif
  299. ifdef SS_NEQ_DGROUP
  300. PSS equ <ss:> ; SS != DS
  301. else
  302. PSS equ <> ; SS == DS
  303. endif
  304. ; Define offset macros:
  305. ; The 32-bit segments will not have 'groups'
  306. ifdef I386
  307. codeoffset equ <offset FLAT:>
  308. dataoffset equ <offset FLAT:>
  309. else
  310. codeoffset equ <offset @code:>
  311. dataoffset equ <offset DGROUP:>
  312. endif
  313. ; The next set of equates deals with the size of SHORTS, INTS, LONGS, and
  314. ; pointers in the 16 and 32 bit versions.
  315. ifdef I386 ;--- 32 bit segment ---
  316. ; parameters and locals
  317. IWORD equ <dword>
  318. LWORD equ <dword>
  319. ; static storage
  320. DINT equ <dd>
  321. DLONG equ <dd>
  322. DSHORT equ <dw>
  323. ; sizes for fixing SP, stepping through tables, etc.
  324. ISIZE equ 4
  325. LSIZE equ 4
  326. SSIZE equ 2
  327. NPSIZE equ 4
  328. FPSIZE equ 4
  329. ; bit shift count to convert byte cnt/ptr to int/long cnt/ptr
  330. ISHIFT equ 2 ; byte-to-int shift count
  331. LSHIFT equ 2 ; byte-to-long shift count
  332. ; sizes dependent upon memory model. dq -vs- df is not yet clear
  333. DNPTR equ <dd> ; near pointer
  334. DFPTR equ <dd> ; far pointer
  335. DCPTR equ <dd offset FLAT:>; 32 bit offset only
  336. DCPTR? equ <dd> ; No seg override for uninitialized values
  337. CPSIZE equ 4
  338. CPDIST equ <near> ; code pointers are near
  339. CPTR equ <near ptr>
  340. DDPTR equ <dd offset FLAT:>
  341. DDPTR? equ <dd>
  342. DPSIZE equ 4
  343. CPWORD equ <dword> ; code pointers are dwords
  344. DPWORD equ <dword> ; data pointers are dwords
  345. APIDIST equ <near> ; all API calls are NEAR in the 32 bit model
  346. ; macro to declare API functions
  347. EXTAPI macro apiname
  348. extrn pascal apiname:near
  349. endm
  350. else ;--- 16-bit segment ---
  351. ; parameters and locals
  352. IWORD equ <word>
  353. LWORD equ <dword>
  354. ; static storage
  355. DINT equ <dw>
  356. DLONG equ <dd>
  357. DSHORT equ <dw>
  358. ; sizes for fixing SP, stepping through tables, etc
  359. ISIZE equ 2
  360. LSIZE equ 4
  361. SSIZE equ 2
  362. NPSIZE equ 2
  363. FPSIZE equ 4
  364. ; bit shift count to convert byte cnt/ptr to int/long cnt/ptr
  365. ISHIFT equ 1 ; byte-to-int shift count
  366. LSHIFT equ 2 ; byte-to-long shift count
  367. ; sizes dependent upon memory model
  368. DNPTR equ <dw> ; near pointer
  369. DFPTR equ <dd> ; far pointer
  370. if sizeC
  371. DCPTR equ <dd> ; 16 bit segment and 16 bit offset
  372. DCPTR? equ <dd>
  373. CPSIZE equ 4
  374. CPDIST equ <far> ; code pointers are far
  375. CPTR equ <far ptr>
  376. CPWORD equ <dword> ; code pointers are dwords
  377. else
  378. DCPTR equ <dw> ; 16 bit offset only
  379. DCPTR? equ <dw>
  380. CPSIZE equ 2
  381. CPDIST equ <near> ; code pointers are near
  382. CPTR equ <near ptr>
  383. CPWORD equ <word> ; code pointers are words
  384. endif
  385. if sizeD
  386. DDPTR equ <dd>
  387. DDPTR? equ <dd>
  388. DPSIZE equ 4
  389. DPWORD equ <dword> ; data pointers are dwords
  390. else
  391. DDPTR equ <dw>
  392. DDPTR? equ <dw>
  393. DPSIZE equ 2
  394. DPWORD equ <word> ; data pointers are words
  395. endif
  396. APIDIST equ <far> ; API calls are FAR in 16 bit model
  397. ; macro to declare API functions
  398. EXTAPI macro apiname
  399. extrn pascal apiname:far
  400. endm
  401. endif ; --- 16/32 segment ---
  402. ; Float/double definitions
  403. ; (currently the same for 16- and 32-bit segments)
  404. FLTSIZE equ 4 ; float
  405. DBLSIZE equ 8 ; double
  406. LDBLSIZE equ 10 ; long double
  407. DFLOAT equ <dd>
  408. DDOUBLE equ <dq>
  409. DLDOUBLE equ <dt>
  410. ;
  411. ; savelist - Generate a list of regs to be saved by the proc 'uses' option.
  412. ;
  413. ; Input:
  414. ; reg1, reg2, reg3, reg4 = registers to be saved across function
  415. ; Output:
  416. ; reglist = text string of registers that can be passed to the 'uses'
  417. ; option on the 'proc' command.
  418. ;
  419. savelist MACRO reg1, reg2, reg3, reg4
  420. local ws, listsize
  421. ws catstr < > ; whitespace char
  422. IFNDEF I386
  423. rbx equ <> ; 8086/286 don't save rbx
  424. ENDIF
  425. IFNB <reg4>
  426. reglist catstr reg1, ws, reg2, ws, reg3, ws, reg4
  427. ELSEIFNB <reg3>
  428. reglist catstr reg1, ws, reg2, ws, reg3, ws
  429. ELSEIFNB <reg2>
  430. reglist catstr reg1, ws, reg2, ws, ws
  431. ELSEIFNB <reg1>
  432. reglist catstr reg1, ws, ws, ws
  433. ELSE
  434. reglist catstr <>
  435. ENDIF
  436. listsize sizestr reglist ; size of register list
  437. IF listsize LE 3 ; if list is only the 3 ws chars...
  438. reglist catstr <>
  439. ENDIF
  440. IFNDEF I386
  441. rbx equ <bx> ; restore rbx
  442. ENDIF
  443. ENDM ; savelist
  444. ;
  445. ; codeseg - Define/declare the standard code segment. Maps to the proper
  446. ; form of the .code directive.
  447. ;
  448. ; Input:
  449. ;
  450. ; Output:
  451. ; .code _TEXT ; for large code models
  452. ; .code ; for small code models
  453. ; assume cs:FLAT ; for 386
  454. ; assume ds:FLAT ; for 386
  455. ; assume es:FLAT ; for 386
  456. ; assume ss:FLAT ; for 386
  457. ;
  458. codeseg MACRO
  459. if sizeC
  460. .code _TEXT
  461. else
  462. .code
  463. endif
  464. ifdef I386
  465. assume ds:FLAT
  466. assume es:FLAT
  467. assume ss:FLAT
  468. endif
  469. ENDM
  470. ;*========
  471. ;*
  472. ;* Debug lab macro
  473. ;*
  474. ;*========
  475. lab macro name
  476. ifdef DEBUG
  477. public pascal name ;; define label public for Symdeb
  478. endif
  479. name:
  480. endm
  481. ;*========
  482. ;*
  483. ;* Conditional jump short macros
  484. ;*
  485. ;*========
  486. irp x,<Z,NZ,E,NE,S,NS,C,NC,P,NP,PE,PO,A,AE,B,BE,NB,G,GE,L,LE>
  487. JS&x equ <j&x short>
  488. endm
  489. ;*========
  490. ;*
  491. ;* Global data definition macros
  492. ;*
  493. ;* Usage:
  494. ;* globalI Name, InitialValue, Repeat
  495. ;*
  496. ;*========
  497. MakeGlobal macro suffix, DataType ;; makes all of the global* macros
  498. global&suffix macro name, data, rep
  499. public name
  500. ifb <rep>
  501. _repeat = 1
  502. else
  503. _repeat = (rep)
  504. endif
  505. name &DataType _repeat dup( data )
  506. endm
  507. endm
  508. MakeGlobal T, dt ; globalT
  509. MakeGlobal Q, dq ; globalQ
  510. MakeGlobal D, dd ; globalD
  511. MakeGlobal W, dw ; globalW
  512. MakeGlobal B, db ; globalB
  513. % MakeGlobal I, <DINT> ; globalI
  514. % MakeGlobal DP, <DDPTR> ; globalDP
  515. % MakeGlobal CP, <DCPTR> ; globalCP
  516. % MakeGlobal FP, <DFPTR> ; globalFP
  517. % MakeGlobal NP, <DNPTR> ; globalNP
  518. ;*========
  519. ;*
  520. ;* Static data definition macros
  521. ;*
  522. ;* Usage:
  523. ;* staticI Name, InitialValue, Repeat
  524. ;*
  525. ;*========
  526. MakeStatic macro suffix, DataType ;; makes all of the static* macros
  527. static&suffix macro name, data, rep
  528. ifdef DEBUG
  529. public pascal name ;; make statics public if DEBUG
  530. endif
  531. ifb <rep>
  532. _repeat = 1
  533. else
  534. _repeat = (rep)
  535. endif
  536. name &DataType _repeat dup( data )
  537. endm
  538. endm
  539. MakeStatic T, dt ; staticT
  540. MakeStatic Q, dq ; staticQ
  541. MakeStatic D, dd ; staticD
  542. MakeStatic W, dw ; staticW
  543. MakeStatic B, db ; staticB
  544. % MakeStatic I, <DINT> ; staticI
  545. % MakeStatic DP, <DDPTR> ; staticDP
  546. % MakeStatic CP, <DCPTR> ; staticCP
  547. % MakeStatic FP, <DFPTR> ; staticFP
  548. % MakeStatic NP, <DNPTR> ; staticNP
  549. ;*========
  550. ;*
  551. ;* Label definition macros
  552. ;*
  553. ;*========
  554. ;*
  555. ;* Label definition macros
  556. ;*
  557. ;* Usage:
  558. ;* labelI Name, {PUBLIC, PASCAL, C}
  559. ;*
  560. ;*========
  561. __MakePublic macro name, option ;; decides if a label should be
  562. ifidni <option>, <PUBLIC> ;; made public
  563. public name
  564. elseifidni <option>, <PASCAL>
  565. public pascal name
  566. elseifidni <option>, <C>
  567. public C name
  568. elseifb <option>
  569. ifdef DEBUG
  570. public pascal name ;; make public if DEBUG
  571. endif
  572. endif
  573. endm
  574. MakeLabel macro suffix, LabelType ;; makes all of the label* macros
  575. %@CatStr(<label>,<suffix>) macro name, option
  576. __MakePublic <name>,<option>
  577. name label &LabelType
  578. endm
  579. endm
  580. MakeLabel T, tbyte ; make labelT
  581. MakeLabel Q, qword ; make labelQ
  582. MakeLabel D, dword ; make labelD
  583. MakeLabel W, word ; make labelW
  584. MakeLabel B, byte ; make labelB
  585. MakeLabel P, proc ; make labelP
  586. MakeLabel FP, far ; make labelFP
  587. MakeLabel NP, near ; make labelNP
  588. % MakeLabel I, IWORD ; make labelI
  589. labelDP macro name, option ;; labelDP
  590. __MakePublic <name>,<option>
  591. ifdef I386
  592. if sizeD
  593. name label fword
  594. else
  595. name label dword
  596. endif
  597. else ;not I386
  598. if sizeD
  599. name label dword
  600. else
  601. name label word
  602. endif
  603. endif ;not I386
  604. endm
  605. labelCP macro name, option ;; labelCP
  606. __MakePublic <name>,<option>
  607. ifdef I386
  608. if sizeC
  609. name label fword
  610. else
  611. name label dword
  612. endif
  613. else ;not I386
  614. if sizeC
  615. name label dword
  616. else
  617. name label word
  618. endif
  619. endif ;not I386
  620. endm
  621. ;*
  622. ;* PUSH16 SegReg - pushes 16 bits in a use32 segment
  623. ;*
  624. PUSH16 macro SegReg
  625. ifdef I386
  626. nop
  627. db 66h ; operand size over-ride
  628. endif ; I386
  629. push SegReg
  630. endm
  631. ;*
  632. ;* JMPFAR16 label - jmps far from a use32 to a use16 segment
  633. ;*
  634. JMPFAR16 macro label
  635. ifndef I386
  636. error <JMPFAR16 can only be used in a use32 code segment>
  637. endif ;I386
  638. nop
  639. db 66h ;; operand size over-ride
  640. db 0eah ;; jmp far immediate op code
  641. dw offset label
  642. dw seg label
  643. endm