|
|
1.1 ! root 1: ; ! 2: ; This is an example of an assembly language program using 286DOS calls. ! 3: ; It creates two threads, one which writes a message to the screen every ! 4: ; two seconds, the other every second. As an example of semaphore usage ! 5: ; the two threads request a semaphore before writing to the screen. ! 6: ; ! 7: ; Copyright (C) Microsoft Corp. 1986 ! 8: ! 9: .286p ; Allow only protect mode instructions ! 10: ! 11: STACK_SIZE equ 400h ; Stack for each thread ! 12: ! 13: STACK segment word stack 'STACK' ! 14: ! 15: dw 2048 dup(?) ! 16: ! 17: STACK ends ! 18: ! 19: DSEG segment word public 'DATA' ! 20: ! 21: Selector dw ? ; selector returned from DOSALLOCSEG ! 22: sem dd 0 ; semaphore ! 23: thread1ID dw ? ; thread id ! 24: ! 25: ; message written from thread 0 ! 26: ; ! 27: hello0 db "thread zero hello", 0dh, 0ah ! 28: HELLO0_SIZE equ ($ - hello0) ! 29: ! 30: ; message written from thread 1 ! 31: ; ! 32: hello1 db "thread ONE hello", 0dh, 0ah ! 33: HELLO1_SIZE equ ($ - hello1) ! 34: ! 35: DSEG ends ! 36: ! 37: DGROUP GROUP DSEG ! 38: assume cs:CSEG, ds:DGROUP ! 39: ! 40: extrn DOSALLOCSEG :FAR ; 286DOS calls used ! 41: extrn DOSCREATETHREAD :FAR ! 42: extrn DOSEXIT :FAR ! 43: extrn DOSSEMCLEAR :FAR ! 44: extrn DOSSEMREQUEST :FAR ! 45: extrn DOSSLEEP :FAR ! 46: extrn DOSWRITE :FAR ! 47: ! 48: CSEG segment byte public 'CODE' ! 49: ! 50: ; allocate memory for the new thread's stack ! 51: ! 52: START: ! 53: push STACK_SIZE ; size requested ! 54: mov bx, SEG DGROUP ! 55: push bx ; push far address of selector ! 56: push offset DGROUP:[Selector] ! 57: push 0 ; not to be shared ! 58: call DOSALLOCSEG ; allocate stack ! 59: or ax, ax ; did an error occur? ! 60: jnz ErrorExit ! 61: ! 62: ; create the new thread ! 63: ! 64: push SEG CSEG ; push far call address for new thread ! 65: push offset CSEG:thread1 ! 66: push bx ; far address of returned thread number ! 67: push offset DGROUP:[thread1ID] ! 68: push DGROUP:[Selector] ; far address of allocated stack ! 69: push STACK_SIZE ! 70: call DOSCREATETHREAD ; create a new thread ! 71: or ax, ax ! 72: jnz ErrorExit ! 73: ! 74: call far ptr thread0 ! 75: ! 76: ErrorExit: ! 77: push 1 ; terminate all threads ! 78: push 1 ; return error code ! 79: call DOSEXIT ; exit program ! 80: ! 81: thread0 PROC FAR ! 82: ! 83: push bp ; set up local stack for access ! 84: mov bp, sp ! 85: ! 86: startThread0: ! 87: push bx ; far address of ram semaphore ! 88: push offset DGROUP:[sem] ! 89: mov ax, -1 ; no timeout, wait forever ! 90: cwd ; convert to long ! 91: push dx ! 92: push ax ! 93: call DOSSEMREQUEST ; request semaphore ! 94: ! 95: ; got semaphore, now write message to screen ! 96: ! 97: push 1 ; file handle for standard out ! 98: push bx ; far address of write buffer ! 99: push offset DGROUP:[hello0] ! 100: push HELLO0_SIZE ; size of write buffer ! 101: lea ax, [bp - 2] ; bytes written ! 102: push ss ! 103: push ax ! 104: call DOSWRITE ; write message ! 105: ! 106: push bx ; far ptr to semaphore ! 107: push offset DGROUP:[sem] ! 108: call DOSSEMCLEAR ; release semaphore ! 109: ! 110: push 0 ; give up processor ! 111: push 2000 ! 112: call DOSSLEEP ! 113: jmp short startThread0 ; loop forever ! 114: ! 115: thread0 ENDP ! 116: ! 117: ! 118: ; This is where the new thread will execute. ! 119: ! 120: thread1 PROC FAR ! 121: ! 122: push bp ; set up local stack access ! 123: mov bp, sp ! 124: ! 125: startThread1: ! 126: push bx ! 127: push offset DGROUP:[sem] ; address of semaphore ! 128: mov ax, -1 ; wait forever ! 129: cwd ; convert to long ! 130: push dx ! 131: push ax ! 132: call DOSSEMREQUEST ; request semaphore ! 133: ! 134: ; got semaphore, now write message to screen ! 135: ! 136: push 1 ; file handle for standard out ! 137: push bx ; write buffer address ! 138: push offset DGROUP:[hello1] ! 139: ! 140: push HELLO1_SIZE ; write buffer size ! 141: ! 142: lea ax, [bp - 2] ; bytes written ! 143: push ss ! 144: push ax ! 145: call DOSWRITE ; write message ! 146: ! 147: push bx ; far ptr to semaphore ! 148: push offset DGROUP:[sem] ! 149: call DOSSEMCLEAR ; release semaphore ! 150: ! 151: push 0 ; give up processor ! 152: push 1000 ! 153: call DOSSLEEP ! 154: jmp short startThread1 ; loop forever ! 155: ! 156: thread1 ENDP ! 157: ! 158: CSEG ends ! 159: end START
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.