寒假有了自己的电脑,三月份要考三级PC,所以看了王爽的汇编语言。看了一遍写了弱弱的四篇笔记。
1. 汇编语言的三种指令:
汇编指令:机器码的助记符,有对应的机器码;(汇编语言的核心,决定汇编语言的特性)
伪指令:没有对应的机器码,有编译器执行,计算机并不执行;
特殊符号:如+ - */ 等,没有对应的机器码。
2. 在内存或磁盘上,指令与数据没有区别,都是二进制信息。
3. 对cpu进行数据的读写需要有三个要素:
地址(找到目的单元)、控制(执行什么操作)、数据(数据信息)。
4.N根地址总线的寻址情况:一次可以寻址的范围是二的N次方,一根线只有高电平和低电平两中情况。
5. N根数据总线的传递数据的能力是一次可以传送N/8个字节。
6.存储器中的基本存储单元是字节(byte);1KB=1024B 2的10次方
7. 每个接口卡上都有自己的Bois比如显卡声卡网卡等等。只不过主板上有一个最基本的系统Bois。 CPU是通过各种扩展卡间接控制各种外设。
显存是指显卡上的RAM,显卡上也有Bois。
8.显存中的数据就呈现在显示器上。
9.内存地址空间:这是一个新概念,就是一个逻辑的内存空间,这个逻辑的内存空间是由主机中所有的Ram和ROM构成的。而CPU对这些不同的内存是同等看待的,这样汇编编程时就必须知道各个内存(包括RAM和ROM)的各个段的起点和终点。
内存空间的容量受到CPU寻址能力的限制。
10. 8086CPU的寄存器可以称之为 字存储器。
11. 进行数据的传送和运算时,汇编指令的两个操作数的位数必须一致。
例如:mov al,bx
Mov bh,ax
Mov ah,20000
Add al,100H
12. 8086cpu的地址总线是20位,可以使寻址范围达到1M。
13.一个X进制的数据左移一位相当于数值乘以X
14. “段地址”中的“段”是自由的,是由CPU根据需要划分的。这样理解是错误的:内存被分成了一段一段的。
15.CPU可以用不同的段地址和偏移地址来确定一个既定的物理地址,只要这一对段地址和偏移地址符合这样的规律就行:段*16+偏=物
对于给定了一个段地址的话,最多可以寻址到的范围是64KB,比如给定段地址1000H,则寻址的范围是10000H到1FFFFH
描述:比如12345H这个单元是由1000与2345来确定的,我们在8086中这么来表示:
1000:2345单元,或者说是在1000段中的2345单元。
所以,总而言之,可以根据需要,将地址连续、地址为16的倍数的地址作为段地址。
16. CS代码段寄存器与IP指令指针寄存器决定了当前要读取指令所在的内存单元。
CS:IP内的内容就是当前将要被读取的指令。
CPU读取指令并执行的过程:CS:IP用地址加法器确定指令的地址 将地址值通过地址总线传到内存序列 按照这个地址找到指令所在的内存单元,这个内存单元里面存储的是
指令的机器码 将此指令的机器码通过数据总线传回CPU并存于指令缓冲器中 而后CPU执行指令进行操作 IP自动加值,加多少就看上一条指令所占用的字节数了。
17. mov是不能改变CS,IP的值的,因为CS IP决定指令的位置。Jmp是可以的称为转移指令。其格式如下:jmp 赋给CS的值:赋给IP的值 eg jmp 2AE3:3
若想只改变IP的值而不想改CS,则其格式为 jmp 某一合法寄存器 eg jmp ax jmp bx
18. debug命令中有好多命令,但常用的就是六种,下面分别做介绍:
(1) R命令,查看各个寄存器中的内容。并在最后一行指出CS:IP所指的内存单元中的内容,即当前要执行指令的机器码。后面是对应的汇编指令。另外还可以用R指令来改变寄存器的值,格式为rax(例子) 后输入将要改的值,再用r命令查看即可。
(2)D命令,查看内存中的内容。格式为d cs:ip 便可以查看以此为初始位置的128个内存单元中的内容。即例如是d 1000:0 则所展示的是从1000:00 到 1000:7F这128个字节中的内容。我们称一个存储器是由128个内存单元组成的编号0-127即128个字节。
D命令右侧出现的是内存中内容对应的ASCII码,对于没有显示的ASCII字符,就 用“.”代替了。连续使用d命令则连续输出内存中的内容。
也可以用D命令来查看设定范围的内存中的内容,格式为 D 段:始偏 终偏
(3)用E命令来修改内存中的内容 格式 e cs:ip 数据一 数据二 数据三 。。。。。这样结合d命令来查看并修改内存中的内容,也可以通过询问的方式来一个一个地修改:(操作详情见王爽P49)也可以通过这种询问的方法来向内存中写入字符(’a’),从这里也可以看出ASCII码与字符的通用性。也可以用E命令来向内存中写入字符串。见P51
(4)用E命令项内存中写入机器码,用U命令查看其含义,T命令执行内存中的机器码。
U命令后面跟作用的地址,可以查看指令含义,是内存中从起始地址开始长度为64个字节机器码。
简单一个T命令会不断执行当前指令,此时debug会呈现出各寄存器中的内容与下一条指令的段偏地址和指令内容。
思考:数据与指令在内存中是没有区别的。如何使用和表达它就是用到了不同的命令。要查看其值就用D,要查看其指令内容或运行就用U和简单的T。
(5)第四条只有在熟悉机器码的情况下才可以熟练运用,所以是不现实的。A命令可以直接将汇编指令写入到内存中。简单地使用A命令可以从当前的这样一个预设地址写入任意条数的命令。可以看出E命令与A命令达到了同样的效果,且用法也是类似的。
PauseP54
19.什么是字单元?即存放一个字型数据(16位)的内存单元由两个连续的字节单元组成。
以后的一个习惯:N地址字单元,其意思是此字单元的其实地址是N。
20.DS存放要访问数据的段地址。
关于MOV指令是不能用立即数给四个段寄存器赋值的,但可以用其他的常用寄存器来中转。这是硬件设计的原因。段寄存器与通用寄存器或内存之间均可以相互直接交流。
因为8086的寄存器是十六位的,所以命令mov ax,[0] 此条指令传送的是一个字数据,即两个字节的长度。且高八位放在ah,低八位放在al。
21.add sub等命令不能作用于段寄存器,使其与通用寄存器之间交流。可用debug命令试验。
22.访问内存中的:指令 用代码段CS与指令指针寄存器IP
数据 用数据段DS与[shuzi] pauseP63
23.对与栈的理解我们目前仅限于这个角度:栈是一种有着特殊访问方式的内存空间,其特殊性就体现在对与此种空间中的数据是 后进先出,先进后出。LIFO
注意:出栈和入栈操作都是以字为单位进行的。
24.栈顶的段地址存放在SS中,偏移地址存放在SP中。SS:SP始终指向栈顶位置是此栈中字单元的低地址位置。SP初始值在栈底,其数值是大数。入栈时,栈顶从高地址到低地址方向增长。
25.空栈时,栈中无元素。此时SS:SP指向栈空间外的第一个内存单元。
8086系列CPU无法对越栈进行判断。没有设计这样的一种寄存器。这也算是一种缺陷。
所以我们在编程的时候就必须自己操心栈的越界问题,要根据最大可能用到的栈空间来设置栈的大小。
26.PUSH POP指令可以使栈与通用寄存器,段寄存器,内存单元之间进行自由交流。
27. 对于一段内存,可以作为代码的存储空间,可以作为数据的存储空间,也可以作为栈的存储空间,关键看CPU内部的各段寄存器和对应的偏移地址寄存器是如何设定的。
28.DEBUG命令的T命令在执行修改段寄存器的SS时,SP的修改工作也紧接着就执行了。
其原因还要涉及到以后要讲的中断机制。
29.源程序 编译 目标文件 连接 可执行文件 执行
其中可执行文件.exe包括两部分一个是机器码,一个是此文件的信息,包括程序有多大,占用多少内存单元等。
30.程序返回:一个程序结束后,讲CPU的控制权交给另一个得以使其运行的程序。这个过程就叫做。。。
一般来说,程序如果是在编译阶段出现错误,则其错误应该是语法错误。没有程序返回的话,编译时不会出现错误,即它没有语法错误,但运行时CPU会出现不太正常。
一个典型的正确程序:
Assume cs:abc
Abc segment
Mov ax,2
Add ax,,ax
Mov ax,4c00H
Int 21
Abc ends
end pause90
31. dos系统中.exe的内存加载过程:SA是一个内存中的起始地址,SA后的256个字节是PSP区,DOS就是用PSP来和被加载程序进行通信,PSP后就是程序所在的位置,即程序在SA+10H:0位置开始加载入内存。
程序加载后,DS中存放的值是SA,即PSP的段地址。
32.用debug命令来跟踪EXE程序的每一步的执行过程。格式 debug 1.exe
此时可以用R和U命令来查看此时寄存器和内存中的初始化情况。
然后就用T命令来单步执行各条指令,到了int 21 这个返回命令的时候,就得用P命令来执行它,出现programme terminated normally便程序返回成功,用Q命令可以退出debug,整体返回的顺序是从1.exe返回到debug 在从debug 返回到command。
以上是前四章,