预备知识——汇编篇
Posted 想学习安全的小白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了预备知识——汇编篇相关的知识,希望对你有一定的参考价值。
参考书籍:《汇编语言》(第三版-王爽)
课后练习题答案
第一章:基础知识
- 1位=1bit;1B=8bit
- 地址总线有x根=地址总线宽度为x=寻址能力为
2^x
B - 1KB的存储器有1024个存储单元,编号0-1023,一个存储单元存储1B数据,存储8bit(位)
- 数据总线为x根,可以传送x位的数据,8根传输8位=8bit=1B
- 在存储器中,数据与程序以二进制形式存放
- 随机存储器(RAM):可读可写,必须带电操作,关机后存储内容丢失
- 只读存储器(ROM):只读不可写(现在发展出了可写的,但是写入熟读慢,读出速度快),关机后内容不丢失
- 为了保持兼容性,8086CPU的AX,BX,CX,DX这4个16位寄存器可以分为两个独立的8位寄存器来使用;AX=AH(8-15,高位)+AL(0-7位,低位),BX=BH+BL,CX=CH+CL,DX=DX+DL
- 字节(BYTE)=8bit;字(word)=2B,一个字分为高位字节和低位字
- mov ax,bx是正确的;mov ax,bl是错误的。在进行数据传送时,指令的两个操作对象位数需要保持一致
- 一个数据的2进制形式左移N位,相当于该数据10进制乘以2的N次方;一个数据X进制左移一位,相当于乘以X
第二章:寄存器
- 在内存中,指令和数据没有任何区别都是2进制信息,cpu将CS:IP指向的内存单元中的内容看作指定
- mov(传送指令):用于设置绝大部分寄存器的值
- jmp(转移指令):修改CS,IP寄存器的值,eg:
jmp 2AE3:3
,执行后:CS=2AE3H,IP=0003H,cpu将从2AE33H处读取指令 - 执行语句
mov ax
sub ax,ax
jmp ax
CPU修改4次IP,一条语句一次,识别到jmp后修改IP指向ax(0000H)
第三章:寄存器
- DS寄存器:存放数据的段地址;[…]指偏移量
运行指令
mov bx,1000H
mov ds,bx
mov al,[0]
结果:al寄存器存放了1000:0也就是10000H的数据
注意:不支持将数据直接诵读段寄存器,不能mov ds,1000H
- 段寄存器SS和寄存器SP。任意时刻SS:SP指向栈顶元素,push和pop操作时,CPU从SS和SP中得到栈顶元素
- PUSh操作:先SP=SP-2,空留出位置,再将数据让进去
- POP操作:先将数据送出,在SP=SP+2
- 8086CPU中,无法判断PUSH与POP操作是否越界,只能用户自己判断,发生了越界系统不会报错。
第四章:第一个程序
第五章:[BX]和loop指令
- [bx]:用[0]表示单元的偏移地址,段地址默认在ds中;[bx]同样表示一个内存单元,它的偏移地址在bx中,段地址在ds中
- inc bx:bx内容加1
- CPU执行loop s时,进行两个操作:1、(cx)=(cx)-1;2、判断cx寄存器里面的值,不为零转至标号s处执行,为零执行下一条指令,也就是说执行cx-1次循环
- 段前缀:默认使用ds里面的值作为段地址,还可以使用mov es:[bx] ax,这里es寄存器里的值作为段地址
第六章:包含多个段的程序
- 在代码段中使用数据:其中dw定义字型数据,占2B=16位
assum cs:code
code segment
dw 0123h,0456h,0789h
start: mov bx,0
mov ax,0
mov cx,3
s:add ax,cs:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
code ends
end
用dw定义的数据处于代码的最开始处,使用CS得到代码段,所以0123h偏移地址为0,0456h偏移地址为2,0789h偏移地址为4
- 程序框架:
assum cs:code
code segment
...数据...
start:
...代码...
code ends
end start
- 将数据、代码、栈放入不同的段
assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0456h,0789h
data ends
stack segment
dw 0,0,0
stack ends
code segment
start:mov ax,stack
mov ss,ax 在代码段里将stack与ss寄存器联系起来
mov ax,data
mov ds,ax 如上同理
code ends
end start start指明入口名称,从start开始执行
第七章:更灵活的定位内存地址的方法
- [bx+idata]:bx中的值加上idata
- si与di是两个1字2B16位的寄存器,与ax类似,但不能分成两个8位独立寄存器
- [bx+si]:表示一个内存单元,偏移地址为:(bx)+(si)
- [bx+si+idata]:偏移地址为:(bx)+(si)+idata
第八章:数据处理的两个基本问题
- 在8086CPU中,只有bx,si,di,bp四个寄存器可以用在[…]中表明偏移码
- 只要使用[bp]且没有指定段地址,默认段地址在ss,而不是ds
- 指明处理的数据长度:
mov ax,1和push 字操作
mov al,1 字节操作
mov word ptr ds:[0],1 字操作
mov byte ptr ds:[0],1 字节操作
- div指令
(1)除数:有8位和16位两种,在一个reg或内存单元中
(2)被除数:默认放在AX或AX+DX的组合中;如果除数为8位,被除数应设置为16位,且默认存放在AX中;如果除数为16位,被除数应设置为32位,在DX(高16位)+AX(低16位)组合中存放
(3)结果:如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数;如果除数为16位,则AX存商,DX存余数
- db定义字节型,dw定义字型,dd定义双字型
- dup:用来对数据进行重复定义
第九章:转移指令的原理
- offset:取得标号的偏移地址
- jmp short 标号:imp从下一条指令处地址加上距离目的指令的距离进行转移
- jmp word ptr 内存单元地址:修改IP,使之跳转
- jmp dword ptr 内存单元地址:内存单元开始处存放着两个字,高地址处为目的段地址cs,低地址处为偏移地址IP,cs=内存单元地址+2,IP=内存单元地址
- jcxz:条件转移指令,短转移,机器码指明转移距离,而不是目的地址
- jcxz:当(cx)=0时转移,当(cx)!=0时什么都不做顺序执行
- ret指令:用栈中的数据,修改IP内容实现进转移
(IP)=((ss)*16+(sp))
(sp)=(sp)+2
- retf指令:用栈中数据,修改CS和IP内容实现远转移
(IP)=((ss)*16+(sp))
(sp)=(sp)+2
(CS)=((ss)*16+(sp))
(sp)=(sp)+2
- call指令:将当前的IP或IP+CS压入栈中后,转移到目的地址
call 标号:
(sp)=(sp)-2
((ss)*16+(sp))=(IP)
(IP)=(IP)+16
call far ptr 标号
(sp)=(sp)-2
((ss)*16+(sp))=(CS)
(sp)=(sp)-2
((ss)*16+(sp))=(IP)
入栈后修改CS和IP的值,CS=标号所在段,IP=标号所在偏移量
以上是关于预备知识——汇编篇的主要内容,如果未能解决你的问题,请参考以下文章