指令

  • dw (define word)
    用来定义数据。 dw 0122h,089h,a478h
  • start (伪指令)
    指明程序入口所在,当程序中含有数据段code segment,初始化时cs为code地址,但是程序不应该从这个地址执行,程序应该从程序段执行,在程序段前面加上start来设置ip指向程序段地址
1
2
3
4
5
6
7
8
9
10
11
assume cs:code
code segment
dw 0123h,...,0486h

start: mov ax,code
[程序区]

mov ax,4c00h
int 21h
code ends
end start

实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
assume cs:code,ds:data,ss:stack

data segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends

stack segment
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stack ends

code segment
start: mov ax,stack
mov ss,ax
mov sp,16

mov ax,data
mov ds,ax

push ds:[0]
push ds:[2]
pop ds:[2]
pop ds:[0]

mov ax,4c00h
int 21h
code ends
end start
  • cs的值就是 assume cs:xxx 中指定的xxx地址
  • 若code的地址为 X ,则stack的地址为 X-2 ,data地址为 X-3
    计算方法: 设data地址为 XX,data中的数据大小为 ndatan_{data} 字节,则stack地址 nstackn_{stack} 计算方法:

nstack16=X16+ndata(1) n_{stack}*16=X*16+n_{data} \tag{1}

nstack=(X+ndata÷16)(2) n_{stack}=(X+\lfloor n_{data}\div 16\rfloor) \tag{2}

(1)式利用字节数建立一个等式,(2)式代表nsn_s
code段计算方式同理,看stack段中存储了多少字节(16的倍数),如果是n倍的16,则ncode=nstack+nn_{code}=n_{stack}+n

内存定位

基础知识点:

    and和or指令的用法;
    通过db ‘(字母)’的形式将对应的ASCII码值提取出来,db的意思是define byte;
    字母的大小写转换问题,仔细研究一下ASCII表中大小写字母的区别,差值固定;
    [bx + idata] 的意思是 [(bx)+ idata](意义:为高级语言实现数组提供了便利机制);
    提供了SI,DI两个16位寄存器,但是这两个寄存器并不能拆分成两个8位寄存器,功能和BX相近;
    二重循环问题的处理: 开辟一块栈空间来保存 外层循环的 CX 寄存器的值

结论:

    [idata]用一个常量来表示地址,可用于直接定位一个内存单元;
    [bx]用一个变量来表示内存地址,可用于间接定位一个内存单元;
    [bx+idata]用一个变量和常量表示地址,可在一个其实地址的基础上用变量简洁的定位一个内存单元;
    [bx+si]用两个变量表示地址;
    [bx+si+idata]用两个变量和一个常量表示地址。