📄 ex12_2.asm
字号:
; EX12_2.asm
;
; Program to demonstrate the ENTER and LEAVE instructions in Chapter 12.
;
; This program simulates the following Pascal code:
;
; program EnterLeave;
; var i:integer;
;
; procedure Lex1;
; var j:integer;
;
; procedure Lex2;
; var k:integer;
;
; procedure Lex3;
; var m:integer;
;
; procedure Lex4;
; var n:integer;
; begin
;
; writeln('Lex4');
; for i:= 0 to 3 do
; for j:= 0 to 2 do
; write('(',i,',',j,') ');
; writeln;
; for k:= 1 downto 0 do
; for m:= 1 downto 0 do
; for n := 0 to 1 do
; write('(',m,',',k,',',n,') ');
; writeln;
; end;
;
; begin {Lex3}
;
; writeln('Lex3');
; for i := 0 to 1 do
; for j := 0 to 1 do
; for k := 0 to 1 do
; for m := 0 to 1 do
; writeln(i,j,k,m);
;
; Lex4;
;
; end; {Lex3}
;
; begin {Lex2}
;
; writeln('Lex2');
; for i := 1 downto 0 do
; for j := 0 to 1 do
; for k := 1 downto 0 do
; write(i,j,k,' ');
; writeln;
;
; Lex3;
;
; end; {Lex2}
;
; begin {Lex1}
;
; writeln('Lex1');
; Lex2;
;
; end; {Lex1}
;
; begin {Main (lex0)}
;
; writeln('Main Program');
; Lex1;
;
; end.
.xlist
include stdlib.a
includelib stdlib.lib
.list
.286 ;Allow ENTER & LEAVE.
; Common equates all the procedures use:
wp textequ <word ptr>
disp1 textequ <word ptr [bp-2]>
disp2 textequ <word ptr [bp-4]>
disp3 textequ <word ptr [bp-6]>
; Note: the data segment and the stack segment are one and the same in this
; program. This is done to allow the use of the [bx] addressing mode when
; referencing local and intermediate variables without having to use a
; stack segment prefix.
sseg segment para stack 'stack'
i word ? ;Main program variable.
stk word 2046 dup (0)
sseg ends
cseg segment para public 'code'
assume cs:cseg, ds:sseg, ss:sseg
; Main's activation record looks like this:
;
; | return address |<- SP, BP
; |----------------|
Main proc
mov ax, ss ;Make SS=DS to simplify addressing (there
mov ds, ax ; will be no need to stick "SS:" in front
mov es, ax ; of addressing modes like "[bx]").
print
byte "Main Program",cr,lf,0
call Lex1
Quit: ExitPgm ;DOS macro to quit program.
Main endp
; Lex1's activation record looks like this:
;
; | return address |
; |----------------|
; | Dynamic Link | <- BP
; |----------------|
; | Lex1's AR Ptr | | Display
; |----------------|
; | J Local var | <- SP (BP-4)
; |----------------|
Lex1_J textequ <word ptr [bx-4]>
Lex1 proc near
enter 2, 1 ;A 2 byte local variable at lex level 1.
nop ;Spacer instruction for single stepping.
print
byte "Lex1",cr,lf,0
call Lex2
leave
ret
Lex1 endp
; Lex2's activation record looks like this:
;
; | return address |
; |----------------|
; | Dynamic Link | <- BP
; |----------------|
; | Lex1's AR Ptr | |
; |----------------| | Display
; | Lex2's AR Ptr | |
; |----------------|
; | K Local var | <- SP (BP-6)
; |----------------|
;
; writeln('Lex2');
; for i := 1 downto 0 do
; for j := 0 to 1 do
; for k := 1 downto 0 do
; write(i,j,k,' ');
; writeln;
;
; Lex3;
Lex2_k textequ <word ptr [bx-6]>
k textequ <word ptr [bp-6]>
Lex2 proc near
enter 2, 2 ;A 2-byte local variable at lex level 2.
nop ;Spacer instruction for single stepping.
print
byte "Lex2",cr,lf,0
mov i, 1
ForLpI: mov bx, disp1 ;"J" is at lex level one.
mov Lex1_J, 0
ForLpJ: mov k, 1 ;"K" is local.
ForLpK: mov ax, i
puti
mov bx, disp1
mov ax, Lex1_J
puti
mov ax, k
puti
mov al, ' '
putc
dec k ;Decrement from 1->0 and quit
jns ForLpK ; if we hit -1.
mov bx, disp1
inc Lex1_J
cmp Lex1_J, 2
jb ForLpJ
dec i
jns ForLpI
putcr
call Lex3
leave
ret
Lex2 endp
; Lex3's activation record looks like this:
;
; | return address |
; |----------------|
; | Dynamic Link | <- BP
; |----------------|
; | Lex1's AR Ptr | |
; |----------------| |
; | Lex2's AR Ptr | | Display
; |----------------| |
; | Lex3's AR Ptr | |
; |----------------|
; | M Local var | <- SP (BP-8)
; |----------------|
;
; writeln('Lex3');
; for i := 0 to 1 do
; for j := 0 to 1 do
; for k := 0 to 1 do
; for m := 0 to 1 do
; writeln(i,j,k,m);
;
; Lex4;
;
Lex3_M textequ <word ptr [bx-8]>
m textequ <word ptr [bp-8]>
Lex3 proc near
enter 2, 3 ;2-byte variable at lex level 3.
nop ;Spacer instruction for single stepping.
print
byte "Lex3",cr,lf,0
mov i, 0
ForILp: mov bx, disp1
mov Lex1_J, 0
ForJlp: mov bx, disp2
mov Lex2_K, 0
ForKLp: mov m, 0
ForMLp: mov ax, i
puti
mov bx, disp1
mov ax, Lex1_J
puti
mov bx, disp2
mov ax, Lex2_k
puti
mov ax, m
puti
putcr
inc m
cmp m, 2
jb ForMLp
mov bx, disp2
inc Lex2_K
cmp Lex2_K, 2
jb ForKLp
mov bx, disp1
inc Lex1_J
cmp Lex1_J, 2
jb ForJLp
inc i
cmp i, 2
jb ForILp
call Lex4
leave
ret
Lex3 endp
; Lex4's activation record looks like this:
;
; | return address |
; |----------------|
; | Dynamic Link | <- BP
; |----------------|
; | Lex1's AR Ptr | |
; |----------------| |
; | Lex2's AR Ptr | |
; |----------------| | Display
; | Lex3's AR Ptr | |
; |----------------| |
; | Lex4's AR Ptr | |
; |----------------|
; | N Local var | <- SP (BP-10)
; |----------------|
;
;
; writeln('Lex4');
; for i:= 0 to 3 do
; for j:= 0 to 2 do
; write('(',i,',',j,') ');
; writeln;
; for k:= 1 downto 0 do
; for m:= 1 downto 0 do
; for n := 0 to 1 do
; write('(',m,',',k,',',n,') ');
; writeln;
n textequ <word ptr [bp-10]>
Lex4 proc near
enter 2, 4 ;2-byte local variable at lex level 4.
nop ;Spacer instruction for single stepping.
print
byte "Lex4",cr,lf,0
mov i, 0
ForILp: mov bx, disp1
mov Lex1_J, 0
ForJLp: mov al, '('
putc
mov ax, i
puti
mov al, ','
putc
mov ax, Lex1_J ;Note that BX still contains disp1.
puti
print
byte ") ",0
inc Lex1_J ;BX still contains disp1.
cmp Lex1_J, 3
jb ForJLp
inc i
cmp i, 4
jb ForILp
putcr
mov bx, disp2
mov Lex2_K, 1
ForKLp: mov bx, disp3
mov Lex3_M, 1
ForMLp: mov n, 0
ForNLp: mov al, '('
putc
mov bx, disp3
mov ax, Lex3_M
puti
mov al, ','
putc
mov bx, disp2
mov ax, Lex2_K
puti
mov al, ','
putc
mov ax, n
puti
print
byte ") ",0
inc n
cmp n, 2
jb ForNLp
mov bx, disp3
dec Lex3_M
jns ForMLp
mov bx, disp2
dec Lex2_K
jns ForKLp
leave
ret
Lex4 endp
cseg ends
zzzzzzseg segment para public 'zzzzzz'
LastBytes db 16 dup (?)
zzzzzzseg ends
end Main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -