在汇编中,dw是一个伪指令,解释为 defind word,定义字型数据,例如
dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
dw定义的多个字型数据中间逗号隔开,它们所占的内存空间分别为16个二进制位
与dw相似的,db,即定义字节型数据,占8个二进制位
在代码段使用数据
前面学习了代码段,在代码段使用数据实例, 把8个数据相加到ax中
在定义时,这8个由于前面没有指令,这8个数据会存储在cs段,偏移为0,2,4,…
code segment
assume cs:code
start:
dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
mov bx, 0
mov ax, 0
mov cx, 8
s:
add ax, cs:[bx]
add bx, 2
loop s
mov ax, 4c00h
int 21h
code ends
end start
这里的cs:[bx]是间接寻址,如果[bx]前没有寄存器名称,默认为ds
编译连接,并调试该程序,输入r指令,你会发现第一条命令并不是mov bx, 0
在这个程序中,cs中存下了一些数据,但对汇编程序来说,它总会把指向cs中的数据当成指令,所以当你存下一些数据时,数据会被”错误“的解析为指令
如果我们把start的位置,改在定义数据之后,我们再次编译,会发现第一条指令已经变为正确的mov bx, 0
可以发现在代码段中使用数据,不够规范,我们应该定义多个段,各自做各自的事情,代码段执行代码,数据段保存数据
汇编多个数据段
编写代码,以下实例使用了多个段
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
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
在编译,连接后,使用debug调试程序,会发现,cs段比ds段地址大256(或16的倍数),而ds段比ss段内存地址大256,系统会自动分配足够大小的内存给每个段
如果一个段中的数据占N个字节,则程序加载后,该段实际占有的空间为
16*(16/N+1)
在使用多个段时,如果没有指定入口地址,则默认会从第一个指令开始,那么cs应该放在最前面,ds,ss则应该放在cs后( 强烈建议写start,否则依然容易报错)