实验任务1
任务1-1
assume ds:data, cs:code, ss:stack
data segment
db 16 dup(0)
data ends
stack segment
db 16 dup(0)
stack ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 16
mov ah, 4ch
int 21h
code ends
end start
- 在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = 076C,寄存器(SS) = 076D,寄存器(CS) = 076E
- 假设程序加载后,code段的段地址是X,则,data段的段地址是X-2H, stack的段地址是 X-1H
Initial Program State
- ES and DS registers both point to the segment containing the PSP structure.
- CS equals value specified in the header, relocated by adding the start segment address to it.
- IP equals value specified in the header. Note, that unlike in COM executables, MZ programs don't start at offset 0x100.
- SS equals value specified in the header, relocated, just like CS.
- SP equals value specified in the header.
- AL is 0x00 if the first FCB in the PSP has a valid drive identifier, 0xFF otherwise.
- AH is the same as AL, but for the second FCB in the PSP.
- All other registers may, or may not be set to 0. You should consider them undefined.
Controlling the Segment Order[1]
The assembler normally positions segments in the object file in the order in
which they appear in source code. The linker, in turn, processes object files inthe order in which they appear on the command line. Within each object file, the
linker outputs segments in the order they appear, subject to any group, class,
and .DOSSEG requirements.
任务1-2
assume ds:data, cs:code, ss:stack
data segment
db 4 dup(0)
data ends
stack segment
db 8 dup(0)
stack ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 8
mov ah, 4ch
int 21h
code ends
end start
-
在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = 076C,寄存器(SS) = 076D,寄存器(CS) = 076E
-
假设程序加载后,code段的段地址是X,则,data段的段地址是X-2H, stack的段地址是 X-1H
任务1-3
assume ds:data, cs:code, ss:stack
data segment
db 20 dup(0)
data ends
stack segment
db 20 dup(0)
stack ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 20
mov ah, 4ch
int 21h
code ends
end start
-
在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = 076C,寄存器(SS) = 076E,寄存器(CS) = 0770
-
假设程序加载后,code段的段地址是X,则,data段的段地址是X-4H, stack的段地址是 X-2H
任务1-4
-
在debug中将执行到line17结束、line19之前,记录此时:寄存器(DS) = 076E,寄存器(SS) = 0770,寄存器(CS) = 076C
-
假设程序加载后,code段的段地址是X,则,data段的段地址是X+2H, stack的段地址是 X+4H
任务1-5
-
对于如下定义的段,程序加载后,实际分配给该段的内存空间大小是 $\lceil \frac{N}{16} \rceil$ Bytes。
a physical segment can begin only at memory locations evenly divisible by 16[2]
由于 8086 特殊的寻址方式,段首地址只能是 16 的倍数。
-
使用MASM,实际表现是四个程序均可以运行。使用TASM,无法通过编译。根据 Programmer's Guide[3]:
If you use full segment directives or prefer not to use .STARTUP, you must identify the starting instruction in two steps:
- Label the starting instruction.
- Provide the same label in the END directive.
我认为不指定 starting instruction 的结果是未定义行为是合理的。
实验任务2
assume cs:code
code segment
start:
mov ax, 0B8F0H
mov ds, ax
mov cx, 160
lb:
mov di, cx
mov word ptr [di-2], 0403H
dec cx
loop lb
mov ah, 4ch
int 21h
code ends
end start
实验任务3
assume cs:code
data1 segment
db 50, 48, 50, 50, 0, 48, 49, 0, 48, 49 ; ten numbers
data1 ends
data2 segment
db 0, 0, 0, 0, 47, 0, 0, 47, 0, 0 ; ten numbers
data2 ends
data3 segment
db 16 dup(0)
data3 ends
code segment
start:
mov ax, data3
mov es, ax
mov cx, 10
mov si, 0
lp: mov ax, data1
mov ds, ax
mov ax, ds:[si]
mov es:[si], ax
mov ax, data2
mov ds, ax
mov ax, ds:[si]
add es:[si], ax
inc si
loop lp
mov ah, 4ch
int 21h
code ends
end start
before
after
实验任务4
assume cs:code
data1 segment
dw 2, 0, 4, 9, 2, 0, 1, 9
data1 ends
data2 segment
dw 8 dup(?)
data2 ends
code segment
start:
mov ax, data2
mov es, ax
mov ax, data1
mov ds, ax
mov si, 0
mov di, 8*2
mov cx, 8
lp: sub di, 2
mov ax, word ptr ds:[si]
mov word ptr es:[di], ax
add si, 2
loop lp
mov ah, 4ch
int 21h
code ends
end start
实验任务5
assume cs:code, ds:data
data segment
db 'Nuist'
db 2, 3, 4, 5, 6
data ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, 0b800H
mov es, ax
mov cx, 5
mov si, 0
mov di, 0f00h
s: mov al, [si]
and al, 0dfh
mov es:[di], al
mov al, [5+si]
mov es:[di+1], al
inc si
add di, 2
loop s
mov ah, 4ch
int 21h
code ends
end start
结果
退出前
line 19
如果字符为小写,则将这个字符转为大写。
line 4
颜色信息。参考VGA text mode。
实验任务6
assume cs:code, ds:data
data segment
db 'Pink Floyd '
db 'JOAN Baez '
db 'NEIL Young '
db 'Joan Lennon '
data ends
code segment
start:
mov ax, data
mov ds, ax
mov di, 0
mov cx, 5
lp: add byte ptr [di], 32
add di, 10h
loop lp
mov ah, 4ch
int 21h
code ends
end start
实验任务7
assume cs:code, ds:data, es:tb, ss:stk
data segment
db '1975', '1976', '1977', '1978', '1979'
dw 16, 22, 382, 1356, 2390
dw 3, 7, 9, 13, 28
data ends
tb segment
db 5 dup( 16 dup(' ') ) ;
tb ends
stk segment
db 50 dup(0)
stk ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, tb
mov es, ax
; field 1
mov cx, 5
_1: push cx
mov cx, 4
_2: mov al, [si]
mov es:[di], al
inc si
inc di
loop _2
pop cx
add di, 10h-4
loop _1
; field 2
mov di, 5
mov cx, 5
_3: mov ax, word ptr [si]
mov word ptr es:[di], ax
add si, 2
add di, 10h
loop _3
; field 3
mov di, 10
mov cx, 5
_4: mov ax, word ptr [si]
mov es:[di], ax
; signed div
mov ax, [si-10]
cwd
idiv word ptr es:[di]
mov es:[di+3], ax
add si, 2
add di, 10h
loop _4
ext:
mov ah, 4ch
int 21h
code ends
end start
before
after