标签:ali out 信息 默认 通用 检测 偶数 zoom 操作符
目录
mount c: d:\asm
c:
//d盘下的文件是自行创建其中包含debug.exe就可以了
set number
color evening
//保存退出
#### 将源代码 生成最终 的 exe 文件 然后执行
这一部分刚开始跟上做就好了,不用了解清楚
DOSBox代码
masm t1; link t1; // t1 为自己创建的asm文件 //在创建txt文件把后缀改为asm //用vim编辑
asm文件代码
as assume cs:code
code segment
mov bx,0B800H
mov es,bx
mov bx,160*10 + 40*2
mov word ptr es:[bx],5535H
mov ax,4C00H
int 21H
code ends
end
437->>>
\[4* 100+3* 10+7* 1\]
\[4*10^2+3*10^1+7*10^0\]
0.1.2.3就是他在数字中的位置
111->>
\[1*2^2+1*2^1+1*2^0\] >>转换成10进制
数字 | 1 | 0 |
---|---|---|
含义 | 有 | 无 |
位置 | 2 | 1 | 0 |
---|---|---|---|
有代表 | 4 | 2 | 1 |
拆分
\[1 byte = 8 bit\]
\[1 KB = 1024 byte\] >> \[1KB = 2^{10} byte\]
\[1 MB = 1024 * 1KB\] 1MB = 1024 * 1024 byte >> \[1MB = 2^{20} byte\]
\[1 GB = 1024 * 1MB\] >> \[1GB = 2^{30} byte\]
- 汇编指令是 机器指令的 注记符,同机器指令一一对应
- 每一种CPU都有自己的汇编指令集
CPU 可以直接使用的 信息 在存储器中 存放
4.在存储器中指令和数据没用任何区别, 都是二进制数
5.存储器单元从 0 开始 编号
6.一个 存储单元 可以存储 8 个 bit 即 8 为二进制数
7.1byte=8bit 1KB=1024byte 1MB=1024KB 1GB=1024MB
总线地址总线 决定 CPU 的 寻址能力
数据总线 决定 CPU 的 一次传输数据量
控制总线 决定 CPU 的 对其他器件的控制能力
小例子
1.1 B800:0400 回车
1.2 1空格 1空格
1.3 2空格 2空格
1.4 ...
汇编程序员 就是 通过 汇编语言 中的 汇编指令 去修改 寄存器的值 从而 控制 CPU 控制整个计算机
AX,BX,CX,DX
- 他们各自可分为两个 8 位寄存器(only)
\[ax=ah+al\] \[(h==high,l==low)\]- 1 byte = 8 bit(8位寄存器)==字节型数据
2 byte =16 bit(16位寄存器)==字型数据2个字节
一个字型数据==2个字节型数据=高位字节+低位字- 数据与寄存器之间 要 保持一致性,8位寄存器给8位数据,16为寄存器给16位数据
==不区==分大小写
jmp指令 jmp 2000:0 ====> cs==2000,ip===0;
mov ax,1000
jmp ax
==> ip=1000;只能用jmp指令修改cs,ip
1.CPU从cs:ip 所指的内存单元中读取内容,存取到 指令缓存器当中
2.然后IP跳转到下一个指令位置,并且在执行指令缓存器当中的指令
3.重复1。
段地址寄存器 偏移地址寄存器 ds(内存),es,ss(栈),cs sp(栈),bp,si,di,ip,bx
-r 查看和修改寄存器中的内容
-r cs
cs value
enter
-d 查看内存中的内容 段地址加偏移地址
-d ss:00
-v 将机器指令翻译成汇编指令
-a 以汇编指令的格式 在内存中写入一条汇编指令 每次debug都的写
-t 执行当前 cs:ip 所指的机器指令 代码段
-e 可以改写 内存中的内容(数据)
-p 快速执行完loop 指令
-g 地址 ==== 一直执行到 地址 的 位置
一次存放两个字节
内存地址由 段地址 和 偏移地址 构成
其中段地址默认保存在DS寄存器当中
偏移地址由 [address] 保存告知
-a
mov ax,1000
mov bx,2000
push ax
push bx
pop ax
pop bx
push 执行过程
1.sp=sp-2(栈顶标记)
2.传入字型数据pop 执行过程
1.传出字或字节
2.sp=sp+2(栈顶标记)栈顶标记 在 数据(内存地址)的上面 的 内存地址
sp 偏移地址寄存器 ss 段地址寄存器
sp 的变化范围 0~ffffH 32768 个字型数据
call 将指令IP 保存到内存的哪里? ret 可以拿回保存到栈中 为了让 ret 从栈中取回
指令从哪里?数据从哪来?临时性的数据存放到哪里?
exe 文件 的描述信息中 保存的程序入口 地址
然后 系统 通过 描述文件 来设置 cs:ip 和 其它内存
asm 文件 -- 汇编语言(1.汇编指令2.伪指令3.符号体系)
- 汇编指令 由编译器 翻译成010101 的机器指令 最后由 CPU 执行
- 伪指令和符号体系 由编译器执行
- 程序返回功能
把系统加载程序的时候 给程序分配的内存 , 设置的寄存器 返还给系统,因为 系统资源 是有限的
mov ax,4c00
int 21H
## 程序的跟踪 debug + 程序名
cx == 程序长度
PSP区 从 ds:0 开始的 256 个字节
默认代码(目前)
```
assum cs:code
code segment
;填写内容
mov ax,4c00H
int 21H
code ends
end
```
假设 数据段 有 N个字节 则 实际占用 \[(N/16 + 1)*16\] 个
//实验5
assume cs:codesg
a segment
db 1,2,3,4,5,6,7,8
a ends
b segment
db 1,2,3,4,5,6,7,8
b ends
c segment
db 0,0,0,0,0,0,0,0
c ends
codesg segment
start:
mov ax,c
mov es,ax
sub cx,cx
sub bx,bx
add cx,8
addnum: mov ax,a
mov ds,ax
sub dx,dx
mov dl,ds:[bx] ;拿出第一个数据
mov ax,b
mov ds,ax
add dl,ds:[bx] ;拿出第二个数据,并且相加
mov es:[bx],dl
inc bx
loop addnum
mov ax,4c00h
int 21h
codesg ends
end start
and 置为大写 1101 1111b
or 置为小写 0100 0000b
常用格式
- mov ax,[200+bx]
- mov ax,200[bx]
- mov ax,[bx].200
常用格式
mov ax,[bx] [si]
sreg 段地址寄存器
reg 寄存器
在处理数据的时候要 告知 CPU 要处理的数据有多大可以通过一些方法来告知
1. 通过寄存器来指明 如 ==ax==,代表对word操作而 ==al==,代表对byte 操作
2. 无寄存器 则用 ==X ptr== 来表示 X 为byte 或者 word 如 : mov word ptr ds:[0],1
3. 用 push or pop 就不用 声明 因为 栈就是 对字进行操作
用来重复数据
通过栈中的数据来修改 cs 和 ip 同时还会 修改栈顶标志
push ip
jmp near ptr 标号
call far ptr
?assembly call 16 位 reg
call word ptr 内存单元地址
call dword ptr 内存单元地址
assume cs:code,ds:data,ss:stack
data segment
db 'conversation'
data ends
stack segment
db 16 dup(0)
stack ends
code segment
start: mov ax,data
mov ds,ax
mov si,0
mov cx,12
call capital
mov ax,4c00h
int 21h
capital: and byte ptr ds:[si],11011111b
inc si;
loop capital
ret
code ends
end start
assume cs:code,ds:data,ss:stack
data segment
db 'word',0
db 'unix',0
db 'wind',0
db 'good',0
data ends
stack segment
db 128 dup(0)
stack ends
code segment
start: mov ax,data
mov ds,ax
mov cx,4
mov bx,0
s: mov di,bx
call capital
add bx,5
loop s
mov ax,4c00h
int 21h
capital: push cx;执行子程序前压栈
push si
change: mov cl,ds:[si]
mov ch,0
jcxz ok
and byte ptr ds:[si],11011111b
inc si
jmp change
ok: pop si;执行完后弹栈
pop cx
ret
code ends
end start
一个默认放在==AL==,另一个放在==内存字节单元==或者==8位reg==。
结果 默认 ==AX==。
一个默认放在==AX==,另一个放在==内存字单元==或者==16位reg==。
结果 默认 高位在==DX== ,低位在==AX==。
assume cs:code,ds:data,ss:stack
data segment
dw 1,2,3,4,5,6,7,8
dd 0,0,0,0,0,0,0,0
db 'word',0
db 'unix',0
db 'wind',0
db 'good',0
data ends
stack segment
db 128 dup(0)
stack ends
code segment
start: mov ax,data
mov ds,ax
mov si,0
mov bp,0
call r_start
mov ax,4c00h
int 21h
r_start: mov bx,ds:[si]
call cube
mov ds:[16+bp],ax
add si,2
add bp,4
loop r_start
ret
cube: mov ax,bx
mul bx
mul bx
ret
CF标志位Carry Flag
ZF标志位Zero Flag
判断相等
最后结果是否为零
OF标志位Overflow
adc 带进位的加法寄存器
sbb 带借位减法
cmp 比较指令
类似于减法指令 只是不保存结果,只是影响相关的标志位寄存器
可以判断两个操作数的大小 通过 sf of 标志位
sf of 大小 1 0 1<2 0 1 1<2 1 1 1>2 0 0 1>2
检测比较结果的转移指令
指令 含义 检测相关的标志位 je equal zf=1 jne not equal zf=0 jb below cf=0 jnb not below cf=1 ja above cf=0 && zf=1 jna not above cf=1 || zf=1
DF 标志和串传送指令
movsb
movsw
配合rep 使用 rep like loop 由cx 的大小决定 执行 上述 两条指令的 次数
exp
;-========movsb=====
mov cx,16
rep movsb
;循环16次 每次执行完后 si di ++
;========movsw
mov cx,16
rep movsw
;循环16次每次 执行完 si,di --
cld -> df==0++
std -> df==1--
pushf && popf
1. 出现溢出
2. 产生0号中断信息
3. 执行0号中断
4. 返回操作系统
分析:
- 当发生除法溢出时,产生0号中断信息,从而引发中断过程
- 取得中断类型码N
- pushf
- TF=0,IF=0
- push CS
- push IP
- \[(IP)=(N*4),CS=(N*4)+2\]
- 发生0号中断时,Cpu转去执行中断处理程序
- 相关处理
- 向显示缓冲区送字符串
- 返回DOS
- ==do0==
- do0的程序应该放在那里
- 放在0号中断的向量表中0000:0200-0000:02FF
- 中断程序的入口地址放在那里
- cs:0000:0002,ip:0000:0000
总结
- 编写中断处理程序do0
- 将do0送入0000:0200
- 将do0的入口地址送到存储在中断向量表0号表项中
assume cs:code
code segment
start: do0安装程序
设置中断向量表
mov ax,4c00h
int 21h
do0: 显示字符串“overflow”
mov ax,4c00h
int 21h
code ends
end start
访问端口
in al , 60h;把60h中的数据读入al中
;1.cpu 通过地址线 将地址信息 60h 发出
;2.cpu 通过控制总线发出读命令 选择端口所在的芯片 并通知他 要从中读取数据
;3.端口所在的芯片 将60h端口中的数据通过数据线送入cpu
移位指令
左移--> *2
右移–> \2
标签:ali out 信息 默认 通用 检测 偶数 zoom 操作符
原文地址:https://www.cnblogs.com/bgst007/p/12240237.html