学 汇编语言 -- 王爽 笔记
-- munds
1: 计算机是由 cpu,内存,外部储存器,主板,等等 组成
2: cpu 通过 数据总线,地址总线,控制总线 来与外部设备交流
3: cpu 通过 统一地址总线 来控制 各大部件
4: cpu 通过 数据总线 接收和发送 数据到 内存
5: 某些cpu 通过 DMA 来控制 速度比较慢的设备 比如 硬盘,软盘,光盘 等
------------------------------- 废话分割线 ------------------------------------------------------------------------------------------------
cpu 通过各种寄存器来储存临时信息
寄存器有: ax,bx,cx,dx,cs,ds,ss,es
cpu运行一条指令的详细动作是 : 1 从cs寄存器中取值 ,2 把给值作为内存地址发送到地址总线上,3 内存器给cpu发送该地址的内容 ,4 cpu处理内容(这个内容就是计算机指令)
在8086中 所有的寄存器都是16位,在 80386 中 所有的寄存器都是 32位
ax,bx,cx,dx 都是 可以分为 al,ah,等的8位寄存器
ax = ah x 2^8 + al
cpu可以单独的对 al ,ah等8位寄存器直接操作
cpu 可以直接往控制总线上面发送 独立显卡的 所处在的地址 就可以往屏幕上面显示东西拉 ^ _ ^
---------------------------段地址,基地址的概念理解 ------------------------------------------------------------------------------------
注意: 8086的地址总线是20位的,而数据总线是16位的,那么 cpu该怎么去定位一个地址呢? 是直接从16位寄存器中拿出内容,直接把这个内容发送到地址总线上?,但是 寄存器不是16位的吗? 还差四位呀!!!!
于是 8086这些逗比设计员 就把定位一个真正物理地址设计成两部分 1: 段地址 2:基地址 。实际地址 = 段地址 x 16 + 基地址
好吧,这样也行,我也醉了
但是我该怎么去从一个内存提取信息呢?
下面我们来看一个例子:
assume cs:code //assume :伪代码 用于给程序员识别 并不会被汇编器编译为机器码
code segment: // 是
mov ax,0x1000 // 给 ax 赋值
mov ds,ax // 因为 ds 不可以直接接收 立即数 所以 用 ax 作为中间者为ds 设值
mov bx,0x20 //
mov ax,[bx] //
ends //
这个例子中 ax 作为中间变量 为 ds 设值
注意ds为段地址寄存器 而 mov ax,[bx] 这条指令是从 0x1000 x 16 + 0x20 = 0x10020 的地址中取两个字节到ax寄存器。
--------------------------柞堆的理解 ----------------------------------------------------------------------------------------------------
8086中常用 ss 作为 柞的段地址,sp 作为 柞的柞顶 柞示意图: | 0x1000b | <-- sp指向一个内存空间
例子: | 0x1000a | push : 先把sp柞顶寄存器减二
assume cs:code ss:stack | 0x10009 | 再把 ax寄存器中的值压入柞中
code segment: | 0x10008 |
mov ax,0x1000 | 0x10007 | pop : 先从柞中抽出内容
mov ss:ax | 0x10006 | 再把sp寄存器中的值减二
mov ax,0x0b | 0x10005 |
mov sp,ax | 0x10004 |
mov ax,10000 | 0x10003 |
push ax | 0x10002 |
这个例子中 先初始化ss寄存器的值,选定一块地址作为柞 内存 | 0x10001 |
然后初始化sp寄存器的值, 初始化 柞顶为柞底 | 0x10000 |
| 0x0ffff | <-- 柞顶
--------------------------8086汇编语言中的各个段---------------------------------------------------------------------------------------------
一: 代码段
cs :提醒程序员 这里是程序的入口 真正的程序入口是由 start 伪代码决定的
二: 数据段
ds :数据段,可以定义程序的缓存数据所在的地址,大小,(一般在程序代码段的前面125字节处)
三: 柞段
ss :设置柞所在的内存的数据
四: 伪代码
segment :程序员为标签后面代码的地方做一个标志 s1: mov ax,10000 //s1代表 “mov ax,10000" 所在的地址
start : 整个程序的第一个命令入口 用于程序被加载完进内存后设置 cs寄存器的值
--------------------------常见的8086汇编命令 -----------------------------------------------------------------------------------------------
命令 例子
mov R1,idata/R2: modifi of value R1=idata/R2 mov ax,1000 // ax=1000
add R2,R3/idata add 增加 add ax, 1000 // ax=ax+1000
inc REG 相当于c语言里面的自加运算 REG++ inc bx // bx 加一
int int 中断 int 21h //产生中断
loop segment 循环 s1: inc ax
-----
-----
loop s1 // 返回 s1 处 做循环
sub R1,R2: 减法 R1=R2-R1 sub ax,bx // ax = bx - ax
push REG : 入柞 push ax, //把ax寄存器的值压入 ss:sp中
pop REG : 取值 pop ax, //往 ss:sp 中取值并送入ax中
来源:oschina
链接:https://my.oschina.net/u/2247886/blog/625846