汇编:
汇编即是机器指令助记符,机器指令让cpu工作。像是mov、jmp、jcxz等汇编指令都有对应的机器指令。有的是两个字节,有的是三个,有的是一个,有的需要操作码(被操作的数)当然也有一些不要。
汇编语言的思路是:设定一部分空间作为存放数值的地方,一部分空间作为存放程序的地方(就像第几号箱子放什么命令)。通过执行箱子中的命令来操作数据,来实现一些功能。
内存空间:
cpu连接内存,通过控制总线内存发送指令说明要使用哪些空间,然后通过数据总线传输数据到指定空间。cpu内部也有一些寄存器来保留计算过程中的一些值。
16位cpu8086:
寄存器:
-ax(ah, al), bx(bh, bl), cx(ch, cl), dx(dh,dl)(寄存器)
-cs:ip(永远指向将要执行的指令),
-ds:[(bx+si)/(bp+di)+x] ,es:[(bx+si)/(bp+di)+x] (指向内存空间,ds,es必须用寄存器赋值bx,bp不共存,si,di不共存(不能同事出现在一个[ ]中))
- ss:sp(ss为栈的段地址,sp为栈顶,由高向低,不会自己停止,要自己注意栈的长度push/pop入/出栈)
指令:
mov:移动指令
add:加
adc:带进位加法
sub:减法
sbb:带进位减法
mul:ax或者al乘法。都是8位(结果ax)或者都是16位(低位ax,高位dx)
div:除法32位/16位,16位除以8位(结果保存存在问题)
loop:cx不为0则循环
dd:双字
dup:空字节,占位
jmp short prt/near ptr/far ptr/word ptr/dword ptr 标号:一字节跳转,后接一字节偏移量(跳转位置 - jmp字节码后的位置)
jcxz 标号:cx为0则跳转至 标号
call:压栈cs:ip或者ip,进入子程序
ret:出栈ip,结束子程序,返回原程序执行处
retf:出栈cs:ip,结束子程序,返回原程序执行处
cmp ax, bx:比较
push:压栈
pushf:压栈标志寄存器位
popf:出栈标志寄存器的值到标志寄存器
pop:出栈
shl:左移一位
shr:右移一位
int 标号:进入中断程序
示例:
'''
;将下面数据显示在屏幕上
assume cs:code,ss:stack
datasg segment
db '1975', '1976', '1977', '1978', '1979', '1980', '1981', '1982', '1983'
db '1984', '1985', '1986', '1987', '1988', '1989', '1990', '1991', '1992'
db '1993', '1994', '1995'
;以上为21年年份结束地址53h
dd 16, 22, 382, 1356, 2390, 8000, 16000, 24486, 50065, 97479, 140417, 197514
dd 345980, 590827, 803530, 1183000, 1843000, 2759000, 3753000, 4649000, 5937000
;以上为21年的收入起始54h结束地址a7h
dw 3, 7, 9, 13, 28, 38, 130, 220, 476, 778, 1001, 1442, 2258, 2793, 4037, 5635, 8226
dw 11542, 14430, 15257, 17800
;以上为21年的雇员人数起始a8h结束地址d1h
datasg ends
;4字节年份+1字节空格+4字节收入+空格+2字节雇员数+空格+2字节人均收入+空格
table segment
db 21 dup ('year summ ne ?? ')
table ends
swap segment
db 10 dup(0)
swap ends
stack segment
db 16 dup(0)
stack ends
code segment
start:
;将data段数据写入table段, 计算21年的人均收入
mov ax, datasg
mov ds, ax
mov ax, table
mov es, ax
mov bx, 0
mov bp, 0
mov si, 0
mov cx, 21
s1:mov di, 0
mov al, ds:[0+bx+0]
mov es:[bp+di], al
inc di
mov al, ds:[0+bx+1]
mov es:[bp+di], al
inc di
mov al, ds:[0+bx+2]
mov es:[bp+di], al
inc di
mov al, ds:[0+bx+3]
mov es:[bp+di], al
inc di
;年份移动
inc di
mov ax, ds:[054h+bx+0]
mov es:[bp+di], ax
add di ,2
mov ax, ds:[054h+bx+2]
mov es:[bp+di], ax
add di, 3
mov ax, ds:[0a8h+si+0]
mov es:[bp+di], ax
;下面计算人均收入
add di, 3
mov ax, es:[bp+05h]
mov dx, es:[bp+07h]
div word ptr es:[bp+0ah]
mov es:[bp+0dh], ax
push ax
push cx
push dx
push ds
push si
push bx
mov dh, 0 ;行号
mov dl, 3 ;列号
mov cl, 2 ;字符属性
mov si, 0
call show_str
pop bx
pop si
pop ds
pop dx
pop cx
pop ax
add bx, 4
add si, 2
add bp, 10h
loop s1
;以上完成Power idea公司的数据存储,下面开始显示
mov dh, 0 ;行号
mov dl, 3 ;列号
mov cl, 2 ;字符属性
mov ax, table
mov es, ax
mov si, 0
;call show_str
mov ax, 4c00h
int 21h
;显示子程序,输入参数为dh,dl,cl
show_str:
;起始地址B8000H~BFFFFH,行首地址每次加A0H,列每次加2H
mov ax, 0b800h
mov ds, ax
mov ax, 0a0h
mul dh
mov bx, ax
mov ax, 0ah
mul bp
add bx, ax
mov ax, 02h
mul dl
add bx, ax
;以上为计算指定位置的地址,保存在ax中
mov di, 0
mov al, cl
;初始化ds为显存段地址,bx为指定位置地址,al为字符属性
s2: mov cx, 16
s: mov dl, es:[bp+si]
;jcxz ok ;判断是否到结尾处
mov dh, al ;将字符放入dl, 属性放入dh
mov ds:[bx+di], dx
inc si
add di, 2
;jcxz s3
loop s
jmp ok
ok: ret
code ends
end start
'''
网友评论