|
|
1.1 root 1: OS/2 SDK MASM UPDATE
2:
3:
4: Installing the Assembler
5:
6: The OS/2 SDK version of the assembler does not include a SETUP
7: program. You install files by copying them directly from the release
8: disks.
9:
10:
11: Assembly Language Under OS/2
12:
13: This file describes some of the differences between assembly language
14: under OS/2 and assembly language under DOS. It discusses new
15: techniques you will have to learn for protected-mode programs, and
16: summarizes differences in tools used for program development.
17:
18: A Sample Program
19: ----------------
20:
21: The following program is an OS/2 version of the sample programs in
22: Chapter 1 of the Microsoft Macro Assembler Programmer's Guide:
23:
24: TITLE hellos2
25: INCLUDELIB doscalls.lib ; <1>
26: .286
27: .MODEL small
28:
29: ; <2>
30: pushc MACRO pushed, pushed2 ;; Define bind from command line
31: IFDEF bind ;; if you want to bind the program
32: mov ax, pushed pushed2 ;; Push constant for 8088/8086
33: push ax
34: ELSE
35: push pushed pushed2 ;; Push constant for 80186+
36: ENDIF
37: ENDM
38:
39: .STACK 800h ; <3>
40: .DATA
41: message DB "Hello, world.",13,10
42: lmessage EQU $ - message
43: bytesout DD ?
44:
45: .CODE
46: EXTRN DosWrite:FAR, DosExit:FAR ; Declare OS/2 calls <4>
47: start: ; <5>
48:
49: ; DosWrite function used to write to screen <6>
50: ; <7>
51: pushc 1 ; Push 1 as handle for standard output
52: push ds ; Push far address of
53: pushc OFFSET message ; "message"
54: pushc lmessage ; Push length of "message"
55: push ds ; Push far address of
56: pushc OFFSET bytesout ; "bytesout"
57:
58: call DosWrite ; Make API call <8>
59: ; AX contains error code <9>
60: ; Variable "bytesout" contains
61: ; number of bytes written
62:
63: ; DosExit function used to return to DOS
64:
65: pushc 1 ; Push action 1 to end all threads
66: pushc 0 ; Push return code 0
67: call DosExit ; Exit
68:
69: END start
70:
71: Note the following ways in which OS/2 programs differ from comparable
72: DOS programs:
73:
74: 1. OS/2 programs must always be linked with the DOSCALLS library.
75: You can specify this in the source file with the INCLUDELIB
76: directive.
77:
78: 2. OS/2 programs require an 80286 (or higher) processor. This means
79: you safely use instructions that are available on the 80826, but
80: not on earlier processors, since your programs can never run on
81: the earlier processors anyway. However, if you wish to bind the
82: program so that it will work either under OS/2 or DOS, you will
83: probably want to use instructions recognized by all processors.
84: For example, a constant can be pushed directly under the 80286,
85: but it must be loaded into a register first under the 8086. The
86: sample program uses a macro to conditionally handle either case.
87:
88: 3. Since OS/2 uses the stack to pass arguments to DOS calls, you
89: may need a larger stack for OS/2 programs than for comparable
90: DOS programs.
91:
92: 4. OS/2 system calls are far external routines and must be declared
93: as such in the source code.
94:
95: 5. In DOS a data segment must be loaded into DS, but in OS/2 a
96: default data segment (the one declared with .DATA) is
97: automatically loaded into DS.
98:
99: 6. For compatibility with the DOS examples in the Programmer's
100: Guide, the DosWrite function is used to write to the screen. The
101: VioWrtTTY function is a simpler alternative in many cases. See
102: the Microsoft Operating System/2 Programmer's Reference for a
103: complete list of OS/2 functions and their arguments.
104:
105: 7. Arguments are pushed onto the stack using the Pascal calling
106: convention. Passed addresses are always far. The called routine
107: cleans up the stack, so there is no need to pop the arguments
108: after the call.
109:
110: 8. For readability, the OS/2 API (Application Program Interface)
111: calls are given in mixed case (DosWrite rather than DOSWRITE).
112: Actually the routine names are all uppercase, but you can used
113: mixed case because MASM converts names to uppercase. If you are
114: writing routines for a case-sensitive language (such as C) you
115: should give the names in uppercase and use the /MX or /ML
116: assembler option.
117:
118: 9. All OS/2 calls return 0 in AX if the call was successful, or an
119: error code in AX if it was not. If additional information needs
120: to be passed back to the program, it will be placed in an
121: address passed as an argument to the call. For example, DosWrite
122: returns the number of bytes written in the variable ("bytesout"
123: in the example) whose address was passed as the last argument.
124:
125: Assembling, Linking, and Binding
126: --------------------------------
127:
128: Assembly under OS/2 is exactly the same as under DOS. The MASM.EXE
129: program is bound so that it runs in either environment. For example,
130: use the following command line to assemble the sample program for
131: OS/2:
132:
133: MASM hellos2;
134:
135: If you want to assemble program to be bound so that it will run under
136: either OS/2 or DOS, use this command line:
137:
138: MASM /Dbind hellos2;
139:
140: This passes a message to the "pushc" macro to push constants in a
141: format compatible with the 8088/8086.
142:
143: The linker has an additional field for a definition file under OS/2,
144: as described in the CodeView and Utilities manual. This field is not
145: used for the sample file. You must also link with DOSCALLS.LIB (which
146: may be located in the directory specified by the LIB environment
147: variable).
148:
149: If DOSCALLS.LIB is specified in the source file with the INCLUDELIB
150: directive (as in the sample), use the following command line:
151:
152: LINK hellos2;
153:
154: You can also specify DOSCALLS.LIB in the command line:
155:
156: LINK hellos2,,,DOSCALLS;
157:
158: OS/2 applications use dynamic linking: procedure calls are not
159: resolved until the program is loaded into memory. When the program is
160: loaded, the code required by a call is extracted from a dynamic link
161: library and loaded with the program. All OS/2 system calls are
162: contained in dynamic link libraries.
163:
164: The DOSCALLS.LIB library does not contain any code for OS/2 system
165: calls. Instead, it contains dynamic link reference records. The linker
166: uses these records to make the connection between the OS/2 system call
167: in the application and the dynamic link library containing the system
168: procedure.
169:
170: You can write OS/2 programs that run under either OS/2 or MS-DOS 3.0
171: or higher by restricting the OS/2 system calls your program uses. OS/2
172: function calls are known collectively as the applications program
173: interface (API). If you restrict your program to a subset of these
174: functions, known as the Family API, you can write programs that run
175: under both OS/2 and MS-DOS 3.0 or higher. See the Microsoft Operating
176: System/2 Programmer's Reference for a list of the Family API
177: functions.
178:
179: Once you have written, assembled, and linked a program using only
180: Family API functions, you must bind the program using the BIND utility
181: to produce a version that runs under either operating system. Binding
182: resolves references to dynamic link routines so the application runs
183: without the dynamic link libraries under DOS.
184:
185: Because the sample program uses only Family API calls, you can bind it
186: using the following command:
187:
188: BIND hellos2 C:\LIB\DOSCALLS.LIB
189:
190: Note that BIND automatically includes the file API.LIB, so you
191: do not need to specify API.LIB on the command line.
192:
193: To debug OS/2 programs using CodeView, use the protected-mode version,
194: CVP.EXE. The options for specifying debug information are the same as
195: in DOS. For example:
196:
197: MASM /ZI hellos2;
198: LINK /CO hellos2;
199: CVP hellos2
200:
201: Note that you cannot debug bound programs. However, you can debug a
202: protected-mode version of the program. If the program is free of
203: logical errors in protected mode, it should work the same when bound
204: and run under DOS.
205:
206: Register and Memory Consideration
207: ---------------------------------
208:
209: The startup conditions for an OS/2 program are significantly different
210: than conditions for a comparable DOS program. Two major differences
211: are that OS/2 programs do not have a PSP and memory is only allocated
212: for the data and code required by the program.
213:
214: Note these specific differences:
215:
216: o Under OS/2, AX contains the segment value of the start of the
217: program's environment. In other words, AX:0 points to the
218: environment.
219:
220: Under DOS, the word at 2Ch of the Program Segment Prefix (PSP) is
221: the segment value of the start of the environment.
222:
223: o Under OS/2 any program arguments are part of the program's
224: environment. BX contains the starting offset. Thus AX:BX points
225: to the name of the executable program name. It is followed by a
226: null byte and then any command line arguments exactly as typed on
227: the command line. A null terminates the command line.
228:
229: Under DOS, the command line is unrelated to the environment. It
230: starts at byte 81h of the PSP. The length of the command line is
231: in the byte at 80h in the PSP and the first two arguments are
232: parsed into uppercase file-name format at bytes 5Ch and 6Ch
233: respectively of the PSP.
234:
235: o Under OS/2, DS contains the segment of the automatic data
236: segment. This is the segment named DGROUP, and it contains both
237: the stack and data. If you use simplified segment directives,
238: this is the .DATA segment. If you do not use simplified segment
239: directives, you must place one data segment in a group called
240: DGROUP. For example:
241:
242: _DATA SEGMENT WORD PUBLIC 'DATA'
243: .
244: .
245: .
246: _DATA ENDS
247:
248: DGROUP GROUP _DATA
249: ASSUME ds:DGROUP
250:
251: Under DOS (.EXE format), DS points to the PSP. Before using a
252: data segment, you must initialize DS to the segment. Use of a
253: group (such as DGROUP) is optional. For example:
254:
255: _DATA SEGMENT WORD PUBLIC 'DATA'
256: .
257: .
258: .
259: _DATA ENDS
260:
261: ASSUME ds:_DATA
262: .
263: .
264: .
265: mov ax,_DATA
266: mov ds,ax
267:
268: o Under OS/2, only the memory required by the program is allocated.
269: Each segment has an allocated size. Data beyond the allocated
270: boundary cannot be accessed. On startup, DS and SS are the same--
271: the automatic data segment is used both for data and stack. SP
272: and CX point to the end of the allocated automatic data segment.
273: CS:IP points to the start of the code segment.
274:
275: Under DOS, programs attempt to use all of memory on startup. If a
276: program needs to allocate dynamic memory, it must first use a DOS
277: call to adjust the program's memory allocation to match the
278: actual memory use. This is not necessary under OS/2, since the
279: operating system automatically allocates only what the program
280: needs.
281:
282: o Under OS/2, segments are actually selectors managed by the
283: operating system. They are not tied to actual memory addresses
284: and any attempt to do segment arithmetic will fail. All memory
285: allocation must be done through operating system calls.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.