关于taocp的MIX[水上原创]


插图:MIX计算机
MIX计算机
先提下MIX计算机cpu用的寄存器:
AX是用作对数据进行算术运算和操作,A[accumulater]可以独立使用,也可与X[extension]连接使用。
I是Index registers,用于计数或访问可变的存储器地址。
J是Jump address,用于存放与jump相关的地址。
注意
在taocp的MIX中:
一个计算机字是5个字节,一个字节含6位。
I寄存器的内容假想为[+/-][0][0][0][m][n]处理。
J寄存器的内容假想为[+][m][n][0][0][0]处理。

1.  C M ,I(F)
看到上面这个式子,就知道这是个指令的表达形式。
C:command
M:memory
I:index
F:field
当I=0时,可写为 C M(F)

2. 一个这样的指令也是以一个符号位加上一个计算机字存放的:
[+/-] [   ] [   ] [ I ] [ F ] [ C ]
[+/-]:一个符号位
[  ][  ]:占两个字节,即C M ,I(F) 中的 M,就是内存单元的编号(即地址),一个内存单元就是一个计算机字的大小。
[ I ]:占一个字节,表示第几个变址寄存器
[F]:占一个字节,F=8L+R,CM,I(F)通常写成CM,I(L:R),表示该指令操作是相对于某内存单元的第L字节至第R字节表示的内容来做的。 当F为(0:5)时,可写为C M,I,此时若I=0,就写成C M。 在MIX里一个计算机字是5个字节,一个字节含6位。
[C]:占一个字节,C以不同的值存在代表不同的操作指令。

3. 总结一下应该就是用来表示这个指令究竟要做什么。
C 这个指令是干什么吃的。
它要吃的内容是什么呢?M and I 告诉这个指令要吃的数据单元在哪。F告诉它要吃的是数据单元的哪个部分。

4.下面可以看看MIX里具体有哪些C(command)
首先还是举个例子以更好的理解指令的表达形式。
假设存储单元2000的内容如下:
[-][8][6][3][5][4]
指令与指令完成后寄存器A中的内容对照
LDA 2000      -86354
LDA 2000(1:5) +86354
LDA 2000(3:5) +00354
LDA 2000(0:3) -00863
LDA 2000(4:4) +00005
LDA 2000(0:0) -00000
LDA 2000(1:1) +00008


现在可以浏览一下MIX的指令集啦。
MIX指令

下面应该是熟悉mixal的时候了。在总结了MIX指令集后,开始看mixal汇编语言,但我总觉得,在该章最后部分对mixal的语言规则进行解释的过程中,实际上有一个很简单的思想规则。目前只是感觉,不过我一定会抓住它的。我就是要看看taocp是如何对mixal汇编语言下定义的。
但这个时候,我觉得这样一个人折腾,有点受不了。google了一下发现gnu mdk 有一个文档,里面的MIX and MIXAL tutorial 总结的已经很好了,参考起来很方便。而且我也google到了一份taocp的笔记总结,主要是第一章数学准备部分的总结。但在进入后边的排列应用部分之前,我想我应该实际的编写一个题目后再进入。

5.用mixal写的程序结构一般是这样的:
程序还是一行一行来读的。但整体结构上来看
第一列的symbol只是一个自定义的记号,或者是代表某个数值,或者代表所在行指令在内存中的单元地址。
第二列的symbol一般要么是一个MIXAL汇编指令,要么是一个MIX指令集中的某个指令。
第三列,我觉得就叫表达式吧,其含义和写法都和第二列的指令是相关联的,是操作数和操作指令的关系。
以*开头的语句,以及第四列都是注释。

我是用MIXbuilder来调试学习下面这个程序的,以达到能够理解MIX程序的目的。
注意第一列和*都是顶格的,列与列之间是tab键,反正要在MIXbuilder里正确运行程序是这样的情形。
MIXbuilder是看着就会用的,很简单的单步调试工具,可以设置断点,可以打开cpu窗口这句话很奇怪,用下MIXbuilder就知道这是指用鼠标点一个cpu形状的按钮就出现的一个窗口),在程序运行的时候观察寄存器的内容的变化,内存单元的变化一般可观察调试窗口里源代码左边有对应的二进制存在形式的表示变化。

下面这个程序就是taocp里通过求极大值排序的一个例子,也是MIXbuilder自带的示例源程序,我自己做注释是理解这个程序的过程(我的注释是“//”后的部分主要注释指令的本质含义),我不是按从上到下一行行注释的,我想从程序起始运行处开始注释,由于一开始没弄明白,以为ORIG 3000表示程序将从3000执行,其实ORIG 3000只是表示程序加载到内存时的基地址,并不是程序执行的起始点。程序的起始点是START IN X+1(16),但是还是很迷惑,START只是一个自定义的符号,MIXbuilder怎么就直接就从它开始的呢?通看了一下源程序发现这个START还出现在END START 语句中,原来END的作用就是定义程序从哪里开始执行,到哪里结束的。[下面的程序因为我添加了注释,所以不能在MIXbuilder中直接运行调试,请注意]

还有一个东西有必要提一下,在程序的执行过程中有一个LC(Location counter)起着很重要的作用,可以这么说,在你执行某条指令时,这个counter(计数器)正在存放下一条要执行的指令在内存中的地址。而Jump类的指令作用就是直接修改LC的值。可以说程序就是根据LC的指示按序执行的。在MIXbuilder中的cpu窗口中有一个抽象的LC寄存器,可以直接看到LC值的变化。

另外还有一个被taocp称为局部变量的东西也需要提一下,就是下面程序中的1H,2H,1B,2B之类,这些变量都是内存单元地址的表示。用法也很简单。但注意?H(here)只能用在第一列,?B(the closest previous location of ?H)和?F(the closest following location of ?H)只能用在第三列里。

好了,终于可以看看这个程序了。
先总的说一下主程序与子程序之间的跳转.注意这里start,maximum,exit都是自定义的内存单元地址的符号表示。
首先因为end start,所以程序从start开始执行,运行到jmp maximum时跳转到子程序,这时LC的值变成maximum,J寄存器的值变成"LDX, X,1"指令在内存中的地址(MIX系统jmp指令执行时的内部效果). "STJ EXIT"的执行使exit地址的内存单元内容实际上变成了跳转到"LDX,X,1"执行,这些子程序执行到exit时就返回到主程序了。

程序代码注释:
X    EQU      1000
      ORIG    
3000

*  PROGRAM M                          
// 子程序是找出最大值及最大值的位置,思路很简单,不再描述,其中寄存器A用来暂存比较过程中的最大值,寄存器I2用来保存这个最大值的位置,当找到更大的数时,A与I2的内容就要做对应的改变.
MAXIMUM    STJ       EXIT    ;SUBROUTINE LINKAGE
INIT              ENT3    
0 , 1        ; M1: INITIALIZE K  =  N
                     JMP      CHANGEM    ;J 
=  N, M  =  X(N), K  =  N - 1
LOOP           CMPA    X,
3     ;M3: COMPARE
                     JGE       
*+ 3
CHANGEM   ENT2    
0 , 3     ;M4: CHANGE M. J  =  K
                     LDA       X,
3     ;M  =  X(K)
                     DEC3    
1     ;M5: DECREASE K
                     J3P        LOOP    ;M2: ALL TESTED
?
EXIT             JMP       
*     ;RETURN TO MAIN PROGRAM


*  PROGRAM P 
START    IN    X
+ 1 ( 16 )    ;MOD: DEV16 // 从cardreader设备读取16个数,这些数作为字符读入到内存,且共需要16个时间周期完成。其中内存单元1001到1016这16个单元被锁定为cardreader访问。
               JBUS     * ( 16 )    ;MOD: DEV16 // 这条指令会重复执行15次,等待上条读入内存的操作完成对JBUS和JRED这两个命令理解的不太透彻,不过我试验过将此条指令换成JRED *(16),并copy多于15行该条命令进行测试,发现执行15次后,JRED才发生跳转,即表现为重复执行JRED *(16),而且IN命令没有完成时,其他的指令不能访问IN命令锁定的内存单元
               ENT1     16     ;MOD: DEV16 ' S BLOCK SIZE

* CONVERT THE TEXT INPUT FROM DEV16 TO NUMBERS
* TRY:  "     2   34  234 7890   23    1   56    7   34  100    8   58   94  947 2847  666 " // 这是cardreader的输入
                                  
               ENT4    
16            // 这一段是把字符表示转为数字表示,因为cardreader把"     2"写到内存时把空格和2当作字符对待,字符空格在内存里是以值00存在的,字符2在内存里是以值32存在的,必须使用NUM命令把字符值重新翻译为digits,并保存在内存中.这样内存里字符2对应的实际值就是2.
2H          ENTA     0     
               LDX      X,
4
               NUM
               STA      X,
4
               DEC4    
1
               J4P       2B

1H          JMP      MAXIMUM  
// 跳转到子程序M
               LDX      X, 1 // 下面这段内容是利用X寄存器和A寄存器将未排序的最大值与最后一个值在内存中的位置进行交换.
               STA      X, 1
               STX      X,
2
               DEC1    
1    // 未排序的数目减一
               J1P      1B  // 进行下一趟排序即跳转到1H位置再执行一轮子程序
               OUT     X + 1 ( 18 )    ;MOD: DEV18
               HLT
               END     START  
// START是程序的入口点

6.关于timing
        ADD, SUB, all LOAD operations, all STORE operations (including STZ), all shift commands, and all comparison operations take two units of time. 
       MOVE requires one unit plus two for each word moved. 
       MUL requires 10 and DIV requires 12 units. 
       Execution time for floating-point operations is unspecified. 
       All remaining operations take one unit of time, plus the time the computer may be idle on the IN, OUT, IOC, or HLT instructions.
       Note in particular that ENTA takes one unit of time, while LDA takes two units.

      The timing rules are easily remembered because of the fact that, except for shifts, MUL, and DIV, the number of units equals the number of references to memory (including the reference to the instruction itself).
      The ``unit'' of time is a relative measure which we will denote simply by u.  Example: the sequence LDA 1000; INCA 1; STA 1000 takes exactly 5u.

 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值