用汇编语言编写程序

汇编程序–>编译器–>机器码

1
2
3
mov ax, 4c00H

int 21H

相当于return 0,程序结束,把控制权交还给系统

一个有意义的汇编程序中至少要有一个段—-代码段

段定义

段名 segment  ----段的开始

...

段名 ends     ----段的结束

end

汇编程序结束的标记位置

assume

1
assume cs:codesg

将段名为codesg的起始地址放入cs代码段寄存器

完整源程序.asm示例

1
2
3
4
5
6
7
8
9
10
11
12
assume cs:codesg

codesg segment
mov ax,0123
mov bx,0456
add ax,bx
add ax,ax

mov ax,4c00
int 21H
codesg ends
end

编译

使用masm编译源码文件

1
masm p4-1.asm;

生成p4-1.OBJ

使用link连接OBJ文件

1
link p4-1

debug装载程序

1
debug p4-1

r命令查看寄存器得到ds=075a,cs=076a,ip=0000,即程序在内存加载的起始位置为075a:0000,代码起始位置为076a:0000,中间的100H字节为程序段前缀(PSP),作为数据区。cx存放代码长度

loop

loop实现循环

  1. (cx) = (cx) - 1
  2. 判断cx不为0则转至标号执行

例1计算2^12的值

1
2
3
4
5
6
7
8
9
10
11
assume cs:code
code segment
mov ax,2
mov cx,11 ;cx存放循环次数
s: add ax,ax
loop s

mov ax,4c00h
int 21h
code ends
end

例2计算ffff:0006字节单元数据乘3,存储在dx中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
assume cs:code
code segment
mov ax,0ffffh;注意,汇编源程序数据不能以字母开头,ffff前加0
mov ds,ax
mov bx,6
mov al,[bx]
mov ah,0

mov dx,0
mov cx,3
s: add dx,ax
loop s

mov ax,4c00h
int 21h
code ends
end

段前缀

debug里写入mov al,[0],u命令查看是正常的,但是写入源文件编译连接后,翻译出的指令为mov al,00与我们的目的不同(具体原因未知)

因此在源文件中使用内存需要加段前缀

1
2
3
mov ax,2000h
mov ds,ax
mov al,ds:[0]

将数据代码栈分段

例1

实现利用栈将数据逆序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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:
;TODO
;初始化寄存器
;入栈
;出栈

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

初始化寄存器

1
2
3
4
5
mov ax,stack
mov ss,ax
mov sp,20h
mov ax,data
mov ds,ax

注意,代码段寄存器cs可以不赋值,因为会根据cs:code自动赋值,但是ss和ds需要手动赋值

入栈

1
2
3
4
5
    mov bx,0
mov cx,8
s: push [bx]
add bx,2
loop s

出栈

1
2
3
4
5
    mov bx,0
mov cx,8
s0: pop [bx]
add bx,2
loop s0

例2

实现大小写字符转换

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
28
29
30
31
assume cs:codesg,ds:datasg
datasg segment
db 'BaSiC'
db 'iNfOrMaTiOn'
datasg ends

codesg segment
start:
mov ax,datasg
mov ds,ax

mov bx,0
mov cx,5
s:mov al,[bx]
and al,11011111b
mov [bx],al
inc bx
loop s

mov bx,5
mov cx,11
s0:mov al,[bx]
or al,00100000b
mov [bx],al
inc bx
loop s0

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

dup指令

db 3 dup (0);定义3个字节,0,0,0
db 3 dup (0,1,2);定义9个字节,0,1,2,0,1,2,0,1,2
db 2 dup (‘abc’,’ABC’);定义12个字节,’abcABCabcABC’

db - 字节型数据
dw - 字型数据
dd - 双字型数据