3 汇编语言编程
3.1 汇编语言编写程序的工作过程

一个完整的汇编程序示例:
assume cs:codesg
codesg segment
mov ax, 0123H
mov bx, 0456H
add ax, bx
add ax, ax
mov ax, 4c00H
int 21H
codesg ends
end
其中首尾是伪指令,不被CPU执行,但需要编译器执行
倒数第二段相当于return 0,表示程序返回
第二,三段为CPU执行的汇编指令
段分配语句:assume cs:code, ds:data, ss:stack
段名 segment,表示一个段的开始,将内容写入该段内
段名 ends,表示一个段的结束
end,表示程序结束
可执行文件生成过程

记事本写.asm,masm生成.obj,link生成.exe
在编写一个程序的过程中,会得到包括.obj,.lst,.crf,.map在内的中间结果
用debug装载程序
在没有指定DS时,会自动装载CS前的**256(100H)**个字节,作为数据区
故此时CS=DS+10H,CX寄存器的值等于代码的长度
注意程序在int 21处结束,后续为垃圾值
p,g命令
P在遇到子程序,中断时,直接执行所有结果(t时逐条执行)
G可以指定开始运行的代码,直到遇到断点或程序结束
3.2 LOOP指令
实现循环的指令
CPU在收到loop指令时,依次执行以下操作:
- CX = CX - 1
- CX == 0
当CX=0时,循环结束;CX=n,则程序执行n次;CX需要在循环之前指定值,且不能为0(否则执行65536次)
loop程序需要定义一个标号,从标号处到loop,循环
3.3 段前缀
在访问内存单元的指令中,要显示地用段前缀指明
mov al, [0]
mov bl, [0]
最终得到的al=bl=00H,此时需要改为如下
mov al, ds:[0]
mov bl, ss:[0]
例:计算ffff:0~ffff:b内所有值的和的方法
解:add dx, ds:[0]?不行,此时为字型数据相加
add dl, ds:[0]?不行,会溢出
解决方案
mov bx, 0
mov cx, 0bH
s: mov al, ds:[bx]
mov ah, 0
add dx, ax
inc bx #bx += 1
loop s
安全存放数据
在段地址指定,运行时由OS分配空间
可以将CS,DS,SS指定为一个段地址,一般不这么干
3.4 将数据写入代码段
示例代码:
assume cs:code
code segment
dw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H
start: mov ax,0
mov bx, 0h
mov cx, 8
s: add ax,cs:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
code ends
end start
其中 dw表示定义字型数据(define word),还有db(define byte),dd(define double)
用
start:
end start
这个代码段包裹代码,主要是end后的符号和:前的符号需要统一名称
end除了告知结束外,还告知编译器程序代码的入口,与数据做区分