|
|
Microsoft OS/2 SDK 03-01-1988
; ; This is an example of an assembly language program using 286DOS calls. ; It creates two threads, one which writes a message to the screen every ; two seconds, the other every second. As an example of semaphore usage ; the two threads request a semaphore before writing to the screen. ; ; Created by Microsoft Corp. 1986 .286p ; Allow only protect mode instructions STACK_SIZE equ 400h ; Stack for each thread STACK segment word stack 'STACK' dw 2048 dup(?) STACK ends DSEG segment word public 'DATA' Selector dw ? ; selector returned from DOSALLOCSEG sem dd 0 ; semaphore thread1ID dw ? ; thread id ; message written from thread 0 ; hello0 db "thread zero hello", 0dh, 0ah HELLO0_SIZE equ ($ - hello0) ; message written from thread 1 ; hello1 db "thread ONE hello", 0dh, 0ah HELLO1_SIZE equ ($ - hello1) DSEG ends DGROUP GROUP DSEG assume cs:CSEG, ds:DGROUP extrn DOSALLOCSEG :FAR ; MS OS/2 calls used extrn DOSCREATETHREAD :FAR extrn DOSEXIT :FAR extrn DOSSEMCLEAR :FAR extrn DOSSEMREQUEST :FAR extrn DOSSLEEP :FAR extrn DOSWRITE :FAR CSEG segment byte public 'CODE' ; allocate memory for the new thread's stack START: push STACK_SIZE ; size requested mov bx, SEG DGROUP push bx ; push far address of selector push offset DGROUP:[Selector] push 0 ; not to be shared call DOSALLOCSEG ; allocate stack or ax, ax ; did an error occur? jnz ErrorExit ; create the new thread push SEG CSEG ; push far call address for new thread push offset CSEG:thread1 push bx ; far address of returned thread number push offset DGROUP:[thread1ID] push DGROUP:[Selector] ; far address of allocated stack push STACK_SIZE call DOSCREATETHREAD ; create a new thread or ax, ax jnz ErrorExit call far ptr thread0 ErrorExit: push 1 ; terminate all threads push 1 ; return error code call DOSEXIT ; exit program thread0 PROC FAR push bp ; set up local stack for access mov bp, sp startThread0: push bx ; far address of ram semaphore push offset DGROUP:[sem] mov ax, -1 ; no timeout, wait forever cwd ; convert to long push dx push ax call DOSSEMREQUEST ; request semaphore ; got semaphore, now write message to screen push 1 ; file handle for standard out push bx ; far address of write buffer push offset DGROUP:[hello0] push HELLO0_SIZE ; size of write buffer lea ax, [bp - 2] ; bytes written push ss push ax call DOSWRITE ; write message push bx ; far ptr to semaphore push offset DGROUP:[sem] call DOSSEMCLEAR ; release semaphore push 0 ; give up processor push 2000 call DOSSLEEP jmp short startThread0 ; loop forever thread0 ENDP ; This is where the new thread will execute. thread1 PROC FAR push bp ; set up local stack access mov bp, sp startThread1: push bx push offset DGROUP:[sem] ; address of semaphore mov ax, -1 ; wait forever cwd ; convert to long push dx push ax call DOSSEMREQUEST ; request semaphore ; got semaphore, now write message to screen push 1 ; file handle for standard out push bx ; write buffer address push offset DGROUP:[hello1] push HELLO1_SIZE ; write buffer size lea ax, [bp - 2] ; bytes written push ss push ax call DOSWRITE ; write message push bx ; far ptr to semaphore push offset DGROUP:[sem] call DOSSEMCLEAR ; release semaphore push 0 ; give up processor push 1000 call DOSSLEEP jmp short startThread1 ; loop forever thread1 ENDP CSEG ends end START
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.