ICS-09

  • 本节介绍栈的基本结构及其三种用途:
    • 1)中断驱动I/O;
    • 2)一种算数运算机制;
    • 3)二进制补码与ASCII字符串之间的转换算法

栈的基本结构

  • 栈是一种ADT,且特点为LIFO

内存中的实现

  • 常见方式为一段连续内存空间和一个寄存器(栈指针)组成。栈指针,是一个寄存器,它的内容是一个地址值,始终指向栈的顶部(最近被压入的元素)。
  • 压入:每压入一个值到栈中,栈指针先递减,然后将数值存入它的地址位置。
    • PUSH ADD R6,R6,#-1
    •  STR R0,R6,#0
      
    • R6为栈指针,将R0内容存入R6对应内容的值
  • 弹出:每弹出一个元素,需要先通过栈指针提供的地址读取该数值,然后递增栈指针。
    • POP LDR R0,R6,#0
    • ADD R6,R6,#1
      
    • R6为栈指针,取出R6对应内容的值存入R0
  • 下溢出:栈内元素不足以弹出。常用方法是,子程序将执行成功或失败的信息记录在某个寄存器中。R5为0标识成功,否则失败
POP     LD R1,EMPTY
        ADD R2,R6,R1
        BRz Failure
        LDR R0,R6,#0
        ADD R6,R6,#1
        AND R5,R5,#0
        RET
Failure AND R5,R5,#0
        ADD R5,R5,#1
        RET
EMPTY .FILL xC000   ; EMPTY <-- -x4000
  • 上溢出:占空间已全部被占用。同POP程序一样,记录程序执行状态,并返回调用程序再处理。
PUSH    LD R1,MAX
        ADD R2,R6,R1
        BRz Failure
        ADD R6,R6,#-1
        STR R0,R6,#0
        AND R5,R5,#0
        RET
Failure AND R5,R5,#0
        ADD R5,R5,#1
        RET
MAX .FILL xC005     ; MAX <-- -x3FFB
  • 小结:通过子程序POP和PUSH,我们可以将5个内存位置x3FFF~x3FFB,设计为一个栈。如果压入程序,只需,将数据存入R0,执行JSR PUSH,如果弹出程序,只需JSR POP。如果希望改变栈大小,修改BASE和MAX的值即可
  • 最终代码如下
POP             ST R2,Save2
                ST R1,Save1
                LD R1,BASE
                ADD R1,R1,#-1
                ADD R2,R6,R1
                BRz fail_exit
                LDR R0,R6,#0
                ADD R6,R6,#1
                BRnzp success_exit
PUSH            ST R2,Save2
                ST R1,Save1
                LD R1,MAX
                ADD R2,R6,R1
                BRz fail_exit
                ADD R6,R6,#-1
                STR R0,R6,#0
success_exitLD  R1,Save1
                LD R2,Save2
                AND R5,R5,#0
                RET
fail_exit       LD R1,Save1
                LD R2,Save2
                AND R5,R5,#0
                ADD R5,R5,#1
                RET
BASE .FILL xC001
MAX .FILL xC005
Save1 .FILL x0000
Save2 .FILL x0000

中断驱动I/O(第二部分)

  • I/O数据传输的管理能力,传输机制
    • 中断服务程序的启动
    • 中断服务程序的执行
    • 中断服务程序的返回

启动和执行

  • 当一个I/O设备的优先级高于当前执行程序时,他在发出INT信号时将启动中断。从处理器角度,每执行完一条指令之后,都将检查是否存在INT。如果没有,则继续下一条指令的执行,如果检测到INT,则暂停下一条指令的读取
  • 此时,开始中断执行的准备工作,1)保存当前执行程序的状态; 2)装载中断服务程序的工作状态,开始中断请求的服务。
程序状态
  • 程序运行所涉及资源的快照。包括该程序的内存空间和通用寄存器的内容,以及两个重要的寄存器:PC和PSR寄存器(处理器状态寄存器)。
    • PSR[15]代表的是该程序的运行模式,特权模式或非特权模式。
      • 特权模式指能够访问一般程序不可访问的资源
    • PSR[10:8]代表正在执行程序的优先级别(priority level),PL0~PL7
    • PSR[2:0]代表条件码,PSR[2]=N,PSR[1]=Z,PSR[0]=P

被中断程序的状态保存
  • 中断启动的第一个任务就是保存正在运行程序的状态,以使得I/O设备服务完成后,程序可以继续运行。
    • 保存PC:可获取中断返回后的下一条待执行指令
    • 保存PSR:条件码后续程序可能依赖它;优先级提供被中断程序与其他程序相比的迫切程度;特权级别表明了被中断程序可以访问的资源范围
  • LC-3将这些内容保存在一个特殊的栈空间中,称为"超级用户栈",该栈空间进攻特权模式下的程序使用。所有程序都通过R6(栈指针)访问栈空间,超级用户栈也不例外。因此,内部寄存器Saved.SSP和Save.USP分别用于保护两个栈指针的内容。
  • 即在中断服务程序开始之前,R6已装入超级用户栈指针的内容。而PC寄存器和被中断程序的PSR寄存器内容将被压入超级用户栈

中断服务程序的状态装入
  • 大多数处理器采用"矢量中断"的工作方式。在中断情况下,I/O设备在发出中断时,将向处理器传递一个8-bit的矢量值。
  • 在多个设备同时请求中断处理的情况下,优先级最高被选中并传递给处理器,称为INTV。
  • INTV拓展为16-bit的地址,对应"中断矢量表"的某个表项地址。中断矢量表的内存位置是x0100~x01FF,每个表项包含一个中断服务程序的起始地址。
  • 处理器将扩展后中断矢量INTV的地址内容装入PC
  • PSR寄存器装入过程:PSR[2:0]内容初始化为0;PSR[15]设置为0,特权模式;PSR[10:8]设置为中断请求者(设备)的优先级别。
  • 至此,完成中断服务的启动阶段,之后可以运行中断服务程序。

中断服务
  • 此时,PC包含的是中断服务程序的起始地址,所以下一个开始执行的就是中断服务程序,即I/O设备的请求开始被服务。

中断返回

  • 中断服务程序的最后,是中断返回指令RTI。当处理器遇到RTI指令时,意味着I/O设备的请求已经完成。
    • RTI(1000):将PSR和PC的内容弹出超级用户栈,然后将它们填入处理器中正确的位置。

基于栈的算术运算

  • “栈式机"或"零地址机器”:硬件默认时将栈顶部的两个元素当做源操作数,并将它们弹出,送给ALU,之后的相加结果又压回栈顶。 (ADD)
  • 在栈式机中,程序员只需告诉计算机执行ADD,而微结构(microarchitecture)将负责所有的具体操作
  • 加法运算
OpADD       JSR POP       ;first operand
            ADD R5,R5,#0  ;successful?
            BRp Exit      ;if unsuccessful
            ADD R1,R0,#0  ;make room for next
            JSR POP       ;next operand
            ADD R5,R5,#0  ;successful?
            BRp Restore1  ;Resotre pointer
            ADD R0,R0,R1  ;Add
            JSR RangeCheck;chenk result
            BRp Restore2  ;Restore pointer
            JSR PUSH      ;push on the stack
            RET           ;next task
Restore2    ADD R6,R6,#-1
Restore1    ADD R6,R6,#-1
Exit        RET
RangeCheck  LD R5,Neg999
            ADD R4,R0,R5
            BRp BadRange
            LD R5,Pos999
            ADD R4,R0,R5
            BRn BadRange
            AND R5,R5,#0
            RET
BadRange    ST R7,Save
            LEA R0,RangeErrorMsg
            TRAP x22
            LD R7,Save
            AND R5,R5,#0
            ADD R5,R5,#1
            RET
Neg999      .FILL #-999
Pos999      .FILL #999
Save        .FILL x0000
RangeErrorMsg .FILL x000A
              .STRINGZ "Number is illegal"
  • 乘法运算
OpMult      AND R3,R3,#0
            JSR POP
            ADD R5,R5,#0
            BRp Exit
            ADD R1,R0,#0
            JSR POP
            ADD R5,R5,#0
            BRp Restore1
            ADD R2,R0,#0
            BRzp PosMultiplier
            ADD R3,R3,#1
            NOT R2,R2
            ADD R2,R2,#1
PosMultiplier AND R0,R0,#0
              ADD R2,R2,#0
              BRz PushMult

MultLoop    ADD R0,R0,R1
            ADD R2,R2,#-1
            BRp MultLoop

            JSR RangeCheck
            ADD R5,R5,#0
            BRp Restore2

            ADD R3,R3,#0
            BRz PushMult
            NOT R0,R0
            ADD R0,R0,#1
PushMult    JSR PUSH
            RET
Restore2    ADD R6,R6,#-1
Restore1    ADD R6,R6,#-1
Exit        RET
  • 取反运算
OpNeg       JSR POP
            ADD R5,R5,#0
            BRp Exit
            NOT R0,R0
            ADD R0,R0,#1
            JSR PUSH
Exit        RET

数据类型转换

ASCII->二进制

  • 按ASCII字符串方式,将数组存放在LC-3内存中标识ASCIIBUFF起始的三个连续地址中,R1记录起始内存中的有效位数。
  • 依次处理每位数字,对于每位数字,只取其二进制值的最低4位,然后以该值索引对应的数值查找表(不同的数位有不同的表),每个表项的内容是10个数字对应的数值。然后,将每位数值累加入R0。
ASCIItoBinary   AND R0,R0,#0  ;result
                ADD R1,R1,#0  ;test digits
                BRz DoneAtoB  ;no digits

                LD R3,NegASCIIOffset ;-x0030
                LEA R2,ASCIIBUFF

                ADD R2,R2,R1
                ADD R2,R2,#-1

                LDR R4,R2,#0 ;R4<--ones digit
                ADD R4,R4,R3
                ADD R0,R0,R4

                ADD R1,R1,#-1
                BRz  DoneAtoB
                ADD R2,R2,#-1

                LDR R4,R2,#0 ;R4<--tens digit
                ADD R4,R4,R3
                LEA R5,LookUp10
                ADD R5,R5,R4; R5 pointer
                LDR R4,R5,#0
                ADD R0,R0,R4

                ADD R1,R1,#-1
                BRz DoneAtoB
                ADD R2,R2,#-1

                LDR R4,R2,#0 ;R4<--hudreds
                ADD R4,R4,R3
                LEA R5,LookUp100
                ADD R5,R5,R4; R5 pointer
                LDR R4,R5,#0
                ADD R0,R0,R4

DoneAtoB        RET
NegASCIIOffset  .FILL xFFD0
ASCIIBUFF       .BLKW 4
LookUp10        .FILL #0
                .FILL #10
                .FILL #20
                .FILL #30
                .FILL #40
                .FILL #50
                .FILL #60
                .FILL #70
                .FILL #80
                .FILL #90
LookUp100       .FILL #0
                .FILL #100
                .FILL #200
                .FILL #300
                .FILL #400
                .FILL #500
                .FILL #600
                .FILL #700
                .FILL #800
                .FILL #900         
                                    

二进制->ASCII

  • R0数值范围为-999~+999,存放带转换的补码整数,转换后的ASCII字符串存放在ASCIIBUFF起始的4个连续内存位置
BinarytoASCII   LEA R1,ASCIIBUFF
                ADD R0,R0,#0
                BRn NegSign
                LD R2,ASCIIplus
                STR R2,R1,#0
                BRnzp Begin100
NegSign         LD R2,ASCIIminus
                STR R2,R1,#0
                NOT R0,R0
                ADD R0,R0,#1

Begin100        LD R2,ASCIIoffset
                LD R3,Neg100
Loop100         ADD R0,R0,R3
                BRn End100
                ADD R2,R2,#1
                BRnzp Loop100
End100          STR R2,R1,#1
                LD R3,Pos100
                ADD R0,R0,R3

                LD R2,ASCIIoffset
Begin10         LD R3,Neg10
Loop10          ADD R0,R0,R3
                BRn End10
                ADD R2,R2,#1
                BRnzp Loop10
End10           STR R2,R1,#2
                ADD R0,R0,#10
Begin1          LD R2,ASCIIoffset
                ADD R2,R2,R0
                STR R2,R1,#3
                RET
ASCIIplus       .FILL x002B
ASCIImius       .FILL x002D
ASCIIoffset     .FILL x0030
Neg100          .FILL xFF9C
Pos100          .FILL x0064
Neg10           .FILL xFFF6
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值