📄 ex11_1a.asm
字号:
; Ex11_1a.asm
;
; Assembly code to link with a C/C++ program.
; This code directly manipulates the screen giving C++
; direct access control of the screen.
;
; Note: Like PGM11_1.ASM, this code is relatively inefficient.
; It could be sped up quite a bit using the 80x86 string instructions.
; However, its inefficiency is actually a plus here since we don't
; want the C/C++ program (Ex11_1.cpp) running too fast anyway.
;
;
; This code assumes that Ex11_1.cpp is compiled using the LARGE
; memory model (far procs and far pointers).
.xlist
include stdlib.a
includelib stdlib.lib
.list
.386 ;Comment out these two statements
option segment:use16 ; if you are not using an 80386.
; ScrSeg- This is the video screen's segment address. It should be
; B000 for mono screens and B800 for color screens.
ScrSeg = 0B800h
_TEXT segment para public 'CODE'
assume cs:_TEXT
; _Capture- Copies the data on the screen to the array passed
; by reference as a parameter.
;
; procedure Capture(var ScrCopy:array[0..24,0..79] of word);
; var x,y:integer;
; begin
;
; for y := 0 to 24 do
; for x := 0 to 79 do
; SCREEN[y,x] := ScrCopy[y,x];
; end;
;
;
; Activation record for Capture:
;
; | |
; | Previous stk contents |
; -------------------------
; | ScrCopy Seg Adrs |
; -- --
; | ScrCopy offset Adrs |
; -------------------------
; | Return Adrs (offset) |
; -------------------------
; | X coordinate value |
; -------------------------
; | Y coordinate value |
; -------------------------
; | Registers, etc. |
; ------------------------- <- SP
ScrCopy_cap textequ <dword ptr [bp+4]>
X_cap textequ <word ptr [bp-2]>
Y_cap textequ <word ptr [bp-4]>
public _Capture
_Capture proc near
push bp
mov bp, sp
push es
push ds
push si
push di
pushf
cld
mov si, ScrSeg ;Set up pointer to SCREEN
mov ds, si ; memory (ScrSeg:0).
sub si, si
les di, ScrCopy_cap ;Get ptr to capture array.
mov cx, 1000 ;1000 double words on the screen
rep movsd
popf
pop di
pop si
pop ds
pop es
mov sp, bp
pop bp
ret
_Capture endp
; _PutScr- Copies array passed by reference onto the screen.
;
; procedure PutScr(var ScrCopy:array[0..24,0..79] of word);
; var x,y:integer;
; begin
;
; for y := 0 to 24 do
; for x := 0 to 79 do
; ScrCopy[y,x] := SCREEN[y,x];
; end;
;
;
; Activation record for PutScr:
;
; | |
; | Previous stk contents |
; -------------------------
; | ScrCopy Seg Adrs |
; -- --
; | ScrCopy offset Adrs |
; -------------------------
; | Return Adrs (offset) |
; -------------------------
; | BP Value | <- BP
; -------------------------
; | X coordinate value |
; -------------------------
; | Y coordinate value |
; -------------------------
; | Registers, etc. |
; ------------------------- <- SP
ScrCopy_fill textequ <dword ptr [bp+4]>
X_fill textequ <word ptr [bp-2]>
Y_fill textequ <word ptr [bp-4]>
public _PutScr
_PutScr proc near
push bp
mov bp, sp
push es
push ds
push si
push di
pushf
cld
mov di, ScrSeg ;Set up pointer to SCREEN
mov es, di ; memory (ScrSeg:0).
sub di, di
lds si, ScrCopy_cap ;Get ptr to capture array.
mov cx, 1000 ;1000 double words on the screen
rep movsd
popf
pop di
pop si
pop ds
pop es
mov sp, bp
pop bp
ret
_PutScr endp
; GotoXY- Positions the cursor at the specified X, Y coordinate.
;
; procedure gotoxy(y,x:integer);
; begin
; BIOS(posnCursor,x,y);
; end;
;
; Activation record for GotoXY
;
; | |
; | Previous stk contents |
; -------------------------
; | X coordinate value |
; -------------------------
; | Y coordinate value |
; -------------------------
; | Return Adrs (offset) |
; -------------------------
; | Old BP |
; ------------------------- <- BP
; | Registers, etc. |
; ------------------------- <- SP
X_gxy textequ <byte ptr [bp+6]>
Y_gxy textequ <byte ptr [bp+4]>
public _GotoXY
_GotoXY proc near
push bp
mov bp, sp
mov ah, 2 ;Magic BIOS value for gotoxy.
mov bh, 0 ;Display page zero.
mov dh, Y_gxy ;Set up BIOS (X,Y) parameters.
mov dl, X_gxy
int 10h ;Make the BIOS call.
mov sp, bp
pop bp
ret
_GotoXY endp
; ClrScrn- Clears the screen and positions the cursor at (0,0).
;
; procedure ClrScrn;
; begin
; BIOS(Initialize)
; end;
;
; Activation record for ClrScrn
;
; | |
; | Previous stk contents |
; -------------------------
; | Return Adrs (offset) |
; ------------------------- <- SP
public _ClrScrn
_ClrScrn proc near
mov ah, 6 ;Magic BIOS number.
mov al, 0 ;Clear entire screen.
mov bh, 07 ;Clear with black spaces.
mov cx, 0000 ;Upper left corner is (0,0)
mov dl, 79 ;Lower X-coordinate
mov dh, 24 ;Lower Y-coordinate
int 10h ;Make the BIOS call.
push 0 ;Position the cursor to (0,0)
push 0 ; after the call.
call _GotoXY
add sp, 4 ;Remove parameters from stack.
ret
_ClrScrn endp
; tstKbd- Checks to see if a key is available at the keyboard.
;
; function tstKbd:boolean;
; begin
; if BIOSKeyAvail then eat key and return true
; else return false;
; end;
;
; Activation record for tstKbd
;
; | |
; | Previous stk contents |
; -------------------------
; | Return Adrs (offset) |
; ------------------------- <- SP
public _tstKbd
_tstKbd proc near
mov ah, 1 ;Check to see if key avail.
int 16h
je NoKey
mov ah, 0 ;Eat the key if there is one.
int 16h
mov ax, 1 ;Return true.
ret
NoKey: mov ax, 0 ;No key, so return false.
ret
_tstKbd endp
; GetXY- Returns the cursor's current X and Y coordinates.
;
; procedure GetXY(var x:integer; var y:integer);
;
; Activation record for GetXY
;
; | |
; | Previous stk contents |
; -------------------------
; | Y Coordinate |
; --- Address ---
; | |
; -------------------------
; | X coordinate |
; --- Address ---
; | |
; -------------------------
; | Return Adrs (offset) |
; -------------------------
; | Old BP |
; ------------------------- <- BP
; | Registers, etc. |
; ------------------------- <- SP
GXY_X textequ <[bp+4]>
GXY_Y textequ <[bp+8]>
public _GetXY
_GetXY proc near
push bp
mov bp, sp
push es
mov ah, 3 ;Read X, Y coordinates from
mov bh, 0 ; BIOS
int 10h
les bx, GXY_X
mov es:[bx], dl
mov byte ptr es:[bx+1], 0
les bx, GXY_Y
mov es:[bx], dh
mov byte ptr es:[bx+1], 0
pop es
pop bp
ret
_GetXY endp
; PutChar- Outputs a single character to the screen at the current
; cursor position.
;
; procedure PutChar(ch:char);
;
; Activation record for PutChar
;
; | |
; | Previous stk contents |
; -------------------------
; | char (in L.O. byte |
; -------------------------
; | Return Adrs (offset) |
; -------------------------
; | Old BP |
; ------------------------- <- BP
; | Registers, etc. |
; ------------------------- <- SP
ch_pc textequ <[bp+4]>
public _PutChar
_PutChar proc near
push bp
mov bp, sp
mov al, ch_pc
mov ah, 0eh
int 10h
pop bp
ret
_PutChar endp
; PutStr- Outputs a string to the display at the current cursor position.
; Note that a string is a sequence of characters that ends with
; a zero byte.
;
; procedure PutStr(var str:string);
;
; Activation record for PutStr
;
; | |
; | Previous stk contents |
; -------------------------
; | String |
; --- Address ---
; | |
; -------------------------
; | Return Adrs (offset) |
; -------------------------
; | Old BP |
; ------------------------- <- BP
; | Registers, etc. |
; ------------------------- <- SP
Str_ps textequ <[bp+4]>
public _PutStr
_PutStr proc near
push bp
mov bp, sp
push es
les bx, Str_ps
PS_Loop: mov al, es:[bx]
cmp al, 0
je PC_Done
push ax
call _PutChar
pop ax
inc bx
jmp PS_Loop
PC_Done: pop es
pop bp
ret
_PutStr endp
; StartPgm- This is where DOS starts running the program. This is
; a substitute for the C0L.OBJ file normally linked in by
; the Borland C++ compiler. This code provides this
; routine to avoid legal problems (i.e., distributing
; unlinked Borland libraries). You can safely ignore
; this code. Note that the C++ main program is a near
; procedure, so this code needs to be in the _TEXT segment.
extern _main:near
StartPgm proc near
mov ax, _DATA
mov ds, ax
mov es, ax
mov ss, ax
lea sp, EndStk
call near ptr _main
mov ah, 4ch
int 21h
StartPgm endp
_TEXT ends
_DATA segment word public "DATA"
stack word 1000h dup (?)
EndStk word ?
_DATA ends
sseg segment para stack 'STACK'
word 1000h dup (?)
sseg ends
end StartPgm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -