汇编语言学习,十几个人汇编复习

零散记录:

2.9 段寄存器

段寄存器就是提供段地址的。

8086有4个段寄存器:CS、 DS、 SS、 ES

当8086CPU要访问内存时,由着4个段寄存器提供内存单元的段地址。

王爽第三版根据课后练习题顺序,结合课本阅读效果更佳,简单的问题不再指出

  8086CPU寄存器都为16位的,可存放两个字节;AX、BX、CX、DX这4个寄存器是通常用来存放一般性的数据,被称为通用寄存器。
  AX:

2.10 CS和IP

CS和IP是8086CPU中最关键的寄存器,它们指示了CPU当前要读取指令的地址。

CS为代码段寄存器,IP为指令指针寄存器

图片 1

   
 1.初始状态(CS:2000H,IP:0000H,CPU将从内存2000Hx16+0000H处读取指令执行)

   
 2.CS、IP中的内容送入地址加法器(地址加法器完成:物理地址=段地址x16+偏移地址)

     3. 地址加法器将物理地址送入输入输出控制电路

     4. 输入输出控制电路将物理地址20000H送上地址总线

     5. 从内存20000H单元开始存放的机器指令B8 23 01
通过数据总线被送入CPU中

这里我有一个困惑,为什么它知道要读取B8 23
01呢?它是怎么确定这是一个完整的指令?CPU如何判断指令长度这里给出了比较清楚的答案。

     6. 输入输出控制电路将机器指令B8 23 01
送入指令缓冲器(读取这一条指令后,IP中的值自动增加,以使CPU可以读取下一条指令。因当前读入的指令B82301长度为3个字节,所以IP中的值加3,此时CS:IP指向内存单元2000::0003)

     7.执行控制器执行指令 B8 23 01 (即mov ax 0123H)

   
 8.指令被执行后AX中的内容为0123H(此时,CPU将从2000::0003处读取指令)

     9. 重复以上的动作。

总结如下:

(1)从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲区

(2) IP=IP+所读取的指令的长度,从而指向下一条指令

(3) 执行指令、转到步骤(1),重复这个过程。

在8086CPU加电启动或复位后(即CPU刚开始工作时)CS和IP设置为CS=FFFFH,IP=0000H,即在8086PC机刚启动时,CPU从内存FFFF0H单元中读取指令执行,FFFF0H单元中的指令是8086PC机开机后执行的第一条指令。

问题:CPU根据什么奖内存中的信息看作指令?

CPU将CS:IP指向的内存单元中的内容看作指令。

本人才疏学浅,不能保证全部所写正确性,有错请指出。

1.1
CPU的寻址能力是由地址总线决定的,一个地址总线宽度对应一个内存单元。8086有20根地址总线,
CPU数据总线一根传一个bit,8086为16根数据总线,一次传输两个字节。数据总线与寄存器,处理位数相同,对应我们之后学到的最大处理数据指定:word
ptr。
在存储器中数据和程序以二进制码存放,我们用-d查看内存时,用16进制数显示,每个字节空一格。
2.2
段地址与偏移地址
物理地址=段地址x16+偏移地址
8086有20根地址总线,这就是它为什么用两个16位的段地址和偏移地址来合成一个20位的物理地址的原因。
2.3
任意时刻CS:IP指向CPU将要执行的下一步操作,课后练习中有三条指令,因为第三条jmp修改了IP,所以共执行了四次。
jmp指令(注意jmp是一个汇编指令,不能在debug中使用,与考试无关。)
**jmp 段地址:偏移地址 ** 同时修改CS:IP
**jmp 寄存器名 ** 只修改IP 等同于 MOV IP,寄存器名
第二章实验
e命令用来写入机器码
a写汇编指令,写完后用r指令把CS与IP修改到写入指令处,用t命令执行即可。

-r 查看和改变CPU寄存器的内容:
-r ax
后按下enter键将出现:提示输入,输入内容即可改变ax寄存器的内容。
-d 查看内存中的内容:
-d 1000:0 意思就是查看内容地址为10000h-10070h内存中的内容。
-d 1000:0 9查看1000:0-1000:9单元中的内容
-d 1000:10 10查看1000:10内存中的内容
-e 改写内存中的命令:
-e 1000:0 1 ‘a’ 2 ‘b’ 3 ‘c’
向1000:0 1000:2 1000:4单元中写入1,2,3, 向1000:1 1000:3
1000:5单元中写入”a” “b” “c”。
-u 将内存中的机器指令翻译成汇编指令:
-u 1000:0
-t 执行一条机器指令:
执行cs:ip所指向的指令
-a 以汇编指令的格式在内存中写入一条机器指令

3.1
多注意内存中的高位与低位位置。

图片 2

2.11 修改CS、IP的指令

若想同时修改CS、IP的内容,可用形如“jmp 段地址:偏移地址”的指令完成

,如

jmp 2AE3:3,执行后:CS=2AE3H,IP=0003H,CPU将从2AE33H处读取指令

jmp 3:0B16,执行后:CS=0003H,IP=0B16H,CPU将从00B46H读取指令

若想仅修改IP的内容,可用形如“jmp 某一合法寄存器”的指令完成,如

jmp ax,指令执行前,ax=1000H,CS=2000H,IP=0003H

              指令执行后,ax=1000H,CS=2000H,IP=1000H

jmp ax,在含义上好似:mov IP,ax(并不是真的有这样的指令)

问题:内存中存放的机器码和对应的汇编指令情况如图,设CPU初始状态:CS=2000H,IP=0000H,请写出指令执行序列。思考后分析

图片 3

(1)mov ax,6622H

(2)jmp 1000:3

(3)mov ax,0000

(4)mov bx,ax

(5)jmp bx

(6)mov ax 0123H

(7)执行第三步

栈的push与pop

SS:SP

3.7
栈的段地址ss,是一个段寄存器(所有段寄存器都不能直接赋值),我们需要一个寄存器来中转。

寄存器reg:ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si,di;
段寄存器sreg:ds,ss,cs,es;

……

 

2.12 代码段

我们可以根据需要将一组内存单元定义为一个段。我们可以将长度为N(N<=64KB)(代码段也是段啊,所以不能超过64KB)的一组代码,存在一组地址连续,起始地址为16的倍数的内存单元中,我们可以认为定义了一个代码段:

mov ax,0000 (B8 00 00)

add ax,0123H(05 23 01)

mov bx,ax(8B D8)

jmp bx (FF E3)

这段长度为10个字节的指令,存放在123B0H~123B9H的一组内存单元中,我们就可以认为,123B0H~123B9H这段内存是用来存放代码的,是一个代码段,它的段地址为123BH,长度为10个字节。

CPU并不会自动的将我们定义的代码段中的指令当做指令来执行。CPU只认被CS:IP指向的内存单元中的内容为指令。所以要让CPU执行,必须要将CS:IP指向所定义的代码段中的第一条指令的首地址。本例中,我们可设CS=123BH,IP=0000H。

  以8086CPU而言,这四个寄存器都可分为两个可独立使用的8位寄存器使用,以-H和-L表示左右八位;
图片 4

 

    指令mov,add: 左操作数 = 左操作数与右操作数运算结果。

  8086CPU中给出物理地址方法: 两个16位地址合成一个20位物理地址:
    段地址×16+偏移地址 = 物理地址;
  ’段地址×16′
可视为基础地址;内存也以此分段的方式管理内存;段寄存器:CS 和
IP,二者指示了CPU当前要读取的指令的地址,CS为代码段寄存器,IP为指令指针寄存器;若CS中为M,IP中为N, 8086CPU将从内存M×16+N单元开始读取一条指令并执行。

  CS和IP不能通过mov改变,可用 ‘jmp’命令,形如“jmp
段地址:偏移地址”,这是修改了两者的内容,若仅想修改IP的内容,可用“jmp
某一合法寄存器”,如 jmp ax 或 jmp bx。
  最后要注意CPU的工作过程:
    ①从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲区;
    ②IP指向下一条指令;
    ③执行命令。(转到①重复步骤)。

DOS中Debug的使用:
/*关于win10中debug用不了
  1.一个方法是可以通过开机时为出现开机界面时按 f8
进入模式选择命令行模式…

  2.图形界面中:
    假如有debug最好,没有的话win+R输入command;再不行的话看下去;
    我的windows10家庭版没有了debug程序也无法运行command,只能自己想办法了,比如说度娘;emmm,分享一下。
    下载一个DOSBox,再直接打开搜狗搜索下载一个debug.exe;
    安装DOSBox,最好选择安装C盘(系统盘)外的盘,避免出问题,之后打开安装的文件夹的DOSBox
0.74 Options.bat文件,拉到最底部,添加如下代码:

  图片 5

  也可以将代码在DOSBox中输入,但这样做避免每次打开都要输一次。
  命令中D为作为虚拟盘的真实磁盘,:DOSBOX_SELF为自定义的文件夹,之后加入没有自带的debug.exe,将下载的debug.exe放入该文件夹,打开DOSBox输入debug即可使用。

 

  正常使用:

图片 6

*/
  -R:查看、改变CPU寄存器内容;
  查看CS和IP值,比如:

图片 7

  其中CS为073F,IP为0102;就是说CPU当前要读取CS:IP即0x74F2处的指令,而且在debug中还显示出了该内存单元中存放的机器码,为呃。。0000,后面则为翻译的汇编指令。

  用r指令改变寄存器中的值,如:

图片 8

  -D:命令查看内容,形如 d 1000:0,为”-d 段地址 :
偏移地址”形式,会显示接下来的128个单元的内容, 右边为ascii码值;

图片 9

  可以试试 d 1000:9,同样输出128单元内容;再比如 d 1000:9
9可控制输出;

  -E:改写内存中的内容,一种是形如 e 1000:0
回车,会有下一行每个字节值,’.’后面直接输入修改值,空格不修改或继续下一个,回车结束;第二种形如
e 1000:0  “fdfd”   “dfds”  12  121;用-R可查看;但写入的是机器码如:b8
01 00 (mov ax,0001)、b90200(mov cx,0002)、01c8(add
ax,cx),-d命令无法显示代码,可以用-u命令查看(形如u  1000:0)

图片 10

 

  -T命令可用来执行我们写入的指令,但必须先让CS:IP指向欲执行的指令单元,每次一条指令:

图片 11

  各寄存器数值随指令发生变化;

  -A命令以汇编指令形式在内存中写入机器指令:形式:-a 
1000:0(1000:0为输入指令的预设地址)

图片 12

  输入完毕回车结束,-d命令查看机器码。

 

各指令可以说明指令和数据在机器中本质上是一样的。

  查看寄存器信息、修改修改寄存器:-R;

  查看内存单元内容:-D;

  修改内存单元内容:-E;

  解释内存内容为机器码及对应汇编指令:-U;

  执行CS:IP指向的内存单元处:-T;

  写入汇编指令至内存中:-A。

 

  在PC及主板的ROM中写有一个生产日期,在内存FFF00H~FFFFFH的某几个单元,其中内容无法修改,也不能用d的输出长度控制,因为为只读内存区域。

がんばって