精华内容
下载资源
问答
  • 原文地址: 数控机床的运动是由程序控制的,而准备功能和辅助功能是程序段的重要组成部分,也是程序编制过程中的核心问题。目前国际上广泛应用的是ISO...它是使数控机床或数控系统建立起某种加工方式的指令。 G代码

    原文地址:http://blog.163.com/gaochengyi_521/blog/static/51831416200793024555647/

    数控机床的运动是由程序控制的,而准备功能和辅助功能是程序段的重要组成部分,也是程序编制过程中的核心问题。目前国际上广泛应用的是ISO标准,我国根据ISO标准制订了JB/T3208-1999《数控机床穿孔带程序段格式中的准备功能G和辅助功能M的代码》。

    1.  准备功能(G)

    准备功能也叫G功能或G代码。它是使数控机床或数控系统建立起某种加工方式的指令。

    G代码由地址符G和其后面的两位数字组成,从G00~G99共100种。表1为我国JB/T3208-1999标准中规定的G功能的定义。

    表内标有字母a、c、d……字母的是表示所对应的第一列中的G代码为模态代码,标有“*”的为非模态代码。字母相同的为一组,同组的任意两个G代码不能同时出现在一个程序段中。

    2.  辅助功能(M)

    辅助功能也叫M功能或M代码,由地址符M和其后的两位数字组成。它是控制数控机床或数控系统的开、关功能的命令。例如开、停冷却泵,启动主轴正、反转,程序结束等。表2为我国JB/T3208-1999标准中规定的M代码。

    由于数控机床的厂家很多,每个厂家使用的G功能、M功能与ISO标准也不完全相同,因为对于某一台数控机床,必须根据机床说明书的规定进行编程。

    3.  进给功能(F)

    进给功能也称为F功能,用来指定坐标轴移动进给的速度。一般有两种指定方法;

    (1)       代码法

    数控车床分每转进给和每分钟进给两种,用G95和G94指令来区分。F后面跟两位数字,表示机床进给速度数列的序号,它不直接表示进给速度的大小。

    (2)       直接代码法

    F后面的数字就是进给速度的大小。目前大多数数控机床均采用这种方法。

    F代码为模态代码,一经设定后,在未被重新指定前,则表示先前所设定的进给速度持续有效。F代码指令如超过制造厂商所设定的范围时,则以厂家所设定的最高或最低进给速度。

    4.  主轴转速功能(S)

    主轴转速功能也称为S功能,用来指定主轴的转速,用字母S和其后的1~4位数字表示。有恒转速和恒线转速两种指令。S代码只是设定主轴转速的大小,并不会使主轴转动,必须用M03(主轴正转)指令或M04(主轴反转)指令时,主轴才开始转动。

    5.  刀具功能

    刀具功能也称为T功能,在自动换刀的数控机床中,该指令用于选择所需的刀具,同时还用来指定刀具补偿值。一般加工中心程序中T代码的数值直接表示选择的刀具号码。例如T15表示15号刀。在数控车床中的T代码后面的数字即包含所选刀具号,也包含刀具补偿号,例如T0402表示选择4号刀,调用2号刀具补偿参数进行刀具长度和半径的补偿。由于不同的数控系统有着不同的指令方法和含义,具体应用时应参照数控机床的编程说明书。

     

     

     

    数控机床标准G代码

    准备功能字是使数控机床建立起某种加工方式的指令,如插补、刀具补偿、固定循环等。G功能字由地址符G和其后的两位数字组成,从G00—G99共100种功能。JB3208-83标准中规定如下表:

    表 1  准备功能字G
    代码功能作用范围功能代码功能作用范围功能
    G00 点定位G50*刀具偏置0/-
    G01 直线插补G51*刀具偏置+/0
    G02 顺时针圆弧插补G52*刀具偏置-/0
    G03 逆时针圆弧插补G53 直线偏移注销
    G04*暂停G54 直线偏移X
    G05*不指定G55 直线偏移Y
    G06 抛物线插补G56 直线偏移Z
    G07*不指定G57 直线偏移XY
    G08*加速G58 直线偏移XZ
    G09*减速G59 直线偏移YZ
    G10-G16*不指定G60 准确定位(精)
    G17 XY平面选择G61 准确定位(中)
    G18 ZX平面选择G62 准确定位(粗)
    G19 YZ平面选择G63*攻丝
    G20-G32*不指定G64-G67*不指定
    G33 螺纹切削,等螺距G68*刀具偏置,内角
    G34 螺纹切削,增螺距G69*刀具偏置,外角
    G35 螺纹切削,减螺距G70-G79*不指定
    G36-G39*不指定G80 固定循环注销
    G40 刀具补偿/刀具偏置注销G81-G89 固定循环
    G41 刀具补偿--左G90 绝对尺寸
    G42 刀具补偿--右G91 增量尺寸
    G43*刀具偏置--左G92*预置寄存
    G44*刀具偏置--右G93 进给率,时间倒数
    G45*刀具偏置+/+G94 每分钟进给
    G46*刀具偏置+/-G95 主轴每转进给
    G47*刀具偏置-/-G96 恒线速度
    G48*刀具偏置-/+G97 每分钟转数(主轴)
    G49*刀具偏置0/+G98-G99*不指定
    注:*表示如作特殊用途,必须在程序格式中说明

    数控机床标准M代码

    辅助功能字是用于指定主轴的旋转方向、启动、停止、冷却液的开关,工件或刀具的夹紧和松开,刀具的更换等功能。辅助功能字由地址符M和其后的两位数字组成。JB3208-83标准中规定如下表:

    表 2  辅助功能字M
    代码功能作用范围功能代码功能作用范围功能
    M00*程序停止M36*进给范围1
    M01*计划结束M37*进给范围2
    M02*程序结束M38*主轴速度范围1
    M03 主轴顺时针转动M39*主轴速度范围2
    M04 主轴逆时针转动M40-M45*齿轮换档
    M05 主轴停止M46-M47*不指定
    M06*换刀M48*注销M49
    M07 2号冷却液开M49*进给率修正旁路
    M08 1号冷却液开M50*3号冷却液开
    M09 冷却液关M51*4号冷却液开
    M10 夹紧M52-M54*不指定
    M11 松开M55*刀具直线位移,位置1
    M12*不指定M56*刀具直线位移,位置2
    M13 主轴顺时针,冷却液开M57-M59*不指定
    M14 主轴逆时针,冷却液开M60 更换工作
    M15*正运动M61 工件直线位移,位置1
    M16*负运动M62*工件直线位移,位置2
    M17-M18*不指定M63-M70*不指定
    M19 主轴定向停止M71*工件角度位移,位置1
    M20-M29*永不指定M72*工件角度位移,位置2
    M30*纸带结束M73-M89*不指定
    M31*互锁旁路M90-M99*永不指定
    M32-M35*不指定   
    注:*表示如作特殊用途,必须在程序格式中说明
    展开全文
  • (五)指令系统设计

    千次阅读 多人点赞 2019-06-18 20:44:17
    文章目录一、指令系统设计1....具体的指令(1)双操作数指令(2)单操作数指令(3)转移指令(4)无操作数指令二、指令时序1.概念2.时序控制方式(1)同步控制(2)异步控制(3)联合控制三、指令执行过程分析1...


    一个字节:8位
    一个字:16位

    【微操作、微命令、微指令、微程序】
    一条指令的执行过程可以分解为若干更微小的基本操作,并称这种基本操作为微操作。
    控制完成微操作的命令称为微命令。
    能够产生一个或多个微命令的二进制编码就称为微指令。
    通过将完成一条机器指令的一系列微指令存入存储器中,然后再按顺序依次读出执行,从而完成指令的功能。并称这些完成机器指令功能的一系列微指令构成的程序称为微程序。


    一、指令系统设计

    1.字指令(依据字的个数分)

    (1)单字指令和双字指令

    在要设计的CPU中,指令有两种格式:单字指令和双字指令两种(在这里规定一个字为二进制16位)。即有的指令只用一个字构成,而有的指令则需两字构成。

    • 单字指令:该指令由一个字组成(一行)
    • 双字指令:该指令由两个字组成(两行)
      在这里插入图片描述

    (2)bit0~bit7指令寻址方式字段

    从指令表示上:bit3决定是单字指令还是双字指令。
    从指令作用上:寻址方式决定是单字指令还是双字指令。

    在这里插入图片描述
    寄存器寻址和寄存器间接寻址的指令只需一个字即可构成;
    而立即寻址、直接寻址、相对寻址和变址寻址则需要两个字,其中一个字用来表示操作码及寻址方式,另一个字表示立即数、直接地址或偏移量。

    • 单字指令:
      ①寄存器寻址;
      ②寄存器间接寻址;
    • 双字指令:
      ③立即寻址;
      ④直接寻址;
      ⑤相对寻址;
      ⑥变址寻址。

    例子:

    单字指令:
    若指定两个操作数的ADD加法指令的操作码字段为00000001,则指令:ADD AX,[ SI]是一条寄存器间接寻址的单字指令,它由16位二进制编码。00000001 10000110组成(1000表示AX是目的地址,0110表示[SI])。

    双字指令:
    若指令: ADD AX,[2000H]是一条直接寻址的双字指令,该指令由两个16位的字组成,一个为指令码字、一个为直接地址:
    00000001 10001001 为指令操作码字
    00100000 00000000 为直接地址字

    2.操作数指令(依据操作数的个数分)

    在这里插入图片描述

    (1)双操作数指令

    双操作数指令的指令操作码字前缀为0000。

    • ADD AX,[ SI]
    • ADD AX,[2000H]

    (2)单操作数指令

    单操作数指令的指令操作码字为0000 1110。

    • INC [BX]
      假如规定加1指令INC的操作码为00001110 0001,[BX]是0101,则其指令码为:00001110 00010101。
    • INC [DI+1000H]
      00001110 00011101 为指令操作码字
      00010000 00000000 为偏移量字

    (3)转移指令

    转移指令的指令操作码字为0000 1111。

    (4)无操作指令

    无操作指令的指令码前缀是0000 1111 1111.

    3.具体的指令

    (1)双操作数指令

    在这里插入图片描述
    双操作数指令设置有:
    传送指令(MOV)
    与指令(AND)
    减法指令(SUB)
    带进位加法指令(ADC)
    带进位减法指令(SBC)
    比较指令(CMP)
    乘法指令(MUL)
    除法指令(DIV)
    加法指令(ADD)
    或指令(OR)
    异或指令(XOR)

    (2)单操作数指令

    在这里插入图片描述
    单操作数指令设置有:
    调用子程序指令(CALL)
    加1指令(INC)
    减1指令(DEC)
    压入堆栈指令(PUSH)
    弹出堆栈指令(POP)
    取反指令(NOT)
    左移指令(SHL)
    逻辑右移指令(SHR)
    算术右移指令(SAR)
    小循环左移指令(ROL)
    小循环右移指令(ROR)
    大循环左移指令(RCL)
    大循环右移指令(RCR)

    (3)转移指令

    在这里插入图片描述
    尽管这类指令也是单操作数指令,在这里单独列出。设置指令有:
    无条件转移指令(JMP)
    零转移指令(JZ)
    非零转移指令(JNZ)
    有进位转移指令(JC)
    无进位转移指令(JNC)
    大于转移指令(JG)
    大于等于转移指令(JGE)
    高于转移指令(JA)
    高于等于转移指令(JAE)

    显然,在上述条件转移中,JC、JNC、JA、JAE是用于无符号数;而JG、JGE则用于带符号数。

    (4)无操作数指令

    在这里插入图片描述
    无操作数指令主要有:
    子程序返回指令(RET)
    中断返回指令(IRET)
    空操作指令(NOP)
    关中断指令(CLI)
    开中断指令(STI)
    软件中断指令(SWI)
    十进制校正指令(DAA)

    二、指令时序

    1.概念

    指令时序是用来控制程序怎么遵从时间有秩序地执行。
    在这里插入图片描述

    • 指令周期:
      CPU从头到尾执行一条指令所用的时间称为指令周期。
    • 机器周期(CPU周期或总线周期):
      把CPU通过系统总线对内存的一次读或写称为一个机器周期。
      指令周期可以分为三个阶段机器周期:取指令操作码(取指)、指令取操作数(取数)和执行指令(执行).
    • 时钟周期(节拍周期)
      机器周期的进一步细分:
      机器周期是由时钟激励完成的,不同的机器周期所需时钟周期数是不一样的。

    PS:
    在这里插入图片描述
    若是一条无操作数指令,则不需要取操作数,CPU将直接进入执行周期。
    若有操作数,不管是一个还是两个,则进入取操作数的周期。

    2.时序控制方式

    指令时序怎么设计和执行,就是时序控制方式。(将如何根据不同指令形成不同系列控制信号所采用的控制方式称为时序控制方式)

    (1)同步控制

    同步控制
    指令执行或指令中每个控制信号都由事先确定的统一的时序信号进行统一控制。

    • ①定长的机器周期,定长的指令周期
      如每条指令都有3个机器周期,每个机器周期都有4个时钟周期。因此,每条指令的执行时间都是12个时钟周期。
    • ②定长的机器周期,变长的指令周期
      机器周期的长度(时钟周期)是固定不变的,而指令可以由一个二个、三个或更多个机器周期组成
    • ③变长的机器周期,变长的指令周期
    • ④折中方案

    (2)异步控制

    异步控制
    当控制器发出某一操作控制信号后,等待执行部件完成操作后发回“回答”信号,再开始新的操作。

    • 没有统一的时钟对信号进行同步
    • 每条指令的指令周期可由多少不等的机器周期数组成

    (3)联合控制

    同步控制和异步控制相结合的方式。

    • 大部分微操作序列安排在固定的机器周期中
    • 对某些时间难以确定的操作则采用“应答”方式。
      如:CPU访问存储器时,依靠其送来的“READY”信号作为读/写周期的结束。

    PS:
    8086CPU采用同步②(定长的机器周期,变长的指令周期)的方式,并在读/写内存或接口时,利用应答信号READY来决定机器周期的长短。

    三、指令执行过程分析

    从指令时序分析,我们可以把一条指令的执行分为三个大的步骤:取指令操作码、取操作数、执行指令。
    在这里插入图片描述

    1.取指令操作码(取指)

    取指令操作码的过程就是从主存中将指令字取出并放在指令寄存器IR中。而且这一过程对所有的指令(不管是单字指令还是双字指令)都是一样的

    取指过程:

    • PC→AR;首先将PC的内容送地址寄存器AR
    • AR→AB,RD,PC+1→PC;将AR输出到系统总线上,作为主存地址,接着送出读控制信号RD,同时内部程序计数器加1
    • MD→DB,DB→DR;第三步就是将从主存读出的指令字(即操作码)送到数据寄存器DR
    • DR→IR;DR再将指令字送到指令寄存器IR中

    2. 译码取操作数

    (1)检测指令

    检测是哪种操作指令:双操作数指令、单操作数指令、转移指令和无操作数指令。
    在这里插入图片描述

    (2)转移指令

    在这里插入图片描述

    (3)双操作数指令

    在这里插入图片描述
    在这里插入图片描述

    (4)单操作数指令

    在这里插入图片描述
    在这里插入图片描述

    3.指令执行

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    四、微指令控制域

    微指令控制域编码是构成微指令重要的组成部分。微指令在执行时,就是由该控制域的编码产生微命令。

    通常,将微指令分为水平型微指令和垂直型微指令。

    • 水平型微指令可以使多个控制信号同时有效,达到使多个微操作同时发生的效果。(一条微指令定义和执行多个并行微命令)
    • 垂直型微指令类似于机器指令,它利用微操作码的不同编码来表示不同的微操作功能。(一条微指令只实现1~2个微命令。)

    1.水平微指令

    (1)直接表示法

    表示方式:

    • 在微指令的控制域字段中,直接表示法就是直接用一个二进制位表示一种微命令。微命令有多少个,控制字段就有多少位
    • 当某位设定为“1”时,表示该位定义的控制信号有效,为“0”时,表示该位定义的控制信号无效。这样,我们就可以利用一条微指令,同时使多个控制信号有效。
      在这里插入图片描述

    优点:
    由于控制信号直接从微指令控制域的某位获得,不需要译码器(这种设计法也称作不译码法或直接控制法)。可以快速地产生控制信号。

    缺点:

    • 微指令控制字段很长:若计算机系统需要 n 个控制信号,则控制域字段长度为 n 个二进制位。
    • 利用率是非常低的:机器指令执行过程的每一步,只需少量的几个微命令。因此,每一条微指令的控制字段中只有少数几个 1,绝大多数位都是 0(该位无效)。

    (2)字段译码法(字段编码)

    相容信号与互斥信号:

    • 相容信号:可以同时出现。
    • 互斥信号:不可以同时出现。

    【互斥信号为什么不可以同时出现?】
    凡是有可能使状态引起竞争的控制信号都是互斥的:
    ① 总线竞争:所有向内总线 IB 的输出信号必是互斥的。例如,PCout、BXout 等等。这些信号一旦同时出现,必定引起总线竞争,一定会造成严重后果。
    ② 多功能器件的诸多功能必是互斥的。例如,ALU 某一时刻只能完成一种功能,做加法时不可能同时做减法。移位器件不可能同时进行左移和右移。
    ③ CPU 对系统总线的操作是互斥的。CPU 不可能同时进行读写,读时不能写,写时不能读。
    ④ 同一器件的输入和输出是互斥的。例如,BXin,BXout 是互斥的。

    字段编码法:它将控制域分为若干字段,互斥的信号放在同一字段、相容的信号放在不同字段。

    • 直接译码方式:若各字段的编码相互独立,则通过各字段独立译码就可以获得计算机系统的全部控制信号
      在这里插入图片描述
    • 间接译码方式:若某些字段的编码相互关联,则关联字段要通过两级译码才能获得相关的控制信号
      在这里插入图片描述

    【为什么互斥的信号放在同一字段、相容的信号放在不同字段?】
    同一字段只会同时执行一个信号,那么互斥的只有一个;不同字段可以同时执行多个信号,那么可以相容。

    【字段编码法如何生效多个字段的指令,如何不生效某个字段的指令?】
    在每个字段中设计一个无效控制信号NOP的编码来不生效某个字段的指令。控制域的某字段有 m 位,则可以提供 2 m − 1 2^m-1 2m1个控制信号的编码。

    【一种字段编码法的控制域字段】
    在这里插入图片描述
    ① 输出到内总线的命令
    XXout微命令,它们是命令某个寄存器将其内容输出到内总线IB上。
    它们放在一个用 4bit 编码的字段中,若从 0000 到 1011 的编码顺序表示从 NOP 到 Tout,则 PCout微命令必为 1001。该命令即可完成 PC→IB 微操作。
    ② 触发寄存器的命令
    XXin微命令,它们是命令内总线IB上的内容输出到某个寄存器上。
    这些命令用这 4 位编码来表示。同样,若从 0000 到 1100 的编码顺序表示从 NOP 到 Tin,则 PCin微命令
    必为 1001。该命令即可完成 IB→PC 微操作。
    ③ 其他微命令
    根据信号的多少决定该字段编码的位数。例如,ARin的编码应为二进制 10。

    共27位。

    2.垂直型微指令

    在这里插入图片描述
    例子:
    如果 CPU 执行机器指令只需 50 余种微命令,则可用 6 位二进制编码构成微指令的控制字段。因为,一种编码只指定一种微命令,6 位编码有 64 种,足以表示这 50 几种微操作命令。可以想像其构成的微指令一定是很短的。

    3.比较

    在这里插入图片描述

    五、微指令的设计

    1.设计

    共9+4+27=40位。
    在这里插入图片描述

    • NA:若控制存储器的容量为 512 字,微指令采用一地址格式,则地址编码用 9 位即可表示。
    • 后继地址控制字段 AC:设定为 4 位,4 位 AC 编码用于控制顺序执行、无条件转移、两分支转移和多分支转移。
    • 控制域字段:采用水平型编码的字段编码法
      在这里插入图片描述
      【XXout和XXin到底怎么区分?】
    • XXout表示将XX中的数据放到IB内部总线上(取出XX)或者从相应器件(ALU)取出
    • XXin表示将IB内部总线上的数据放到XX中(输入XX)或者向相应器件(ALU)输入

    2.例子

    在这里插入图片描述
    表示PCout,ARin

    六、微操作和微命令

    1.微操作和微命令

    在这里插入图片描述
    微指令是一串微命令的结合。
    微操作和微命令互相转化(其实就是微操作和微指令的互相转化)。

    我们规定一个机器周期由 4 个节拍来实现。

    (1)取指令码周期(取指)FIC

    微操作 取指过程:

    • PC→AR;首先将PC的内容送地址寄存器AR
    • AR→AB,RD,PC+1→PC;将AR输出到系统总线上,作为主存地址,接着送出读控制信号RD,同时内部程序计数器加1
    • MD→DB,DB→DR;第三步就是将从主存读出的指令字(即操作码)送到数据寄存器DR
    • DR→IR;DR再将指令字送到指令寄存器IR中

    对应的取指的微操作命令:

    • W0 PCout,ARin
    • W1 AR→AB,RD,PC+1
    • W2 MD→DB,DRin
    • W3 DRout,IRin

    (2)取操作数周期(取数)FDC

    ① MOV AX, 4000H
    该指令的取操作数周期过程如下:
    W0 PCout,ARin
    W1 AR→AB,RD,PC+1
    W2 MD→DB,DRin
    W3 DRout,AXin
    这里要说明的是,该指令取操作数周期结束,该指令执行也就结束。利用最后的节拍启动下一条指令的 FIC 周期。

    ② ADD BX, [DI]
    该指令的取操作数周期过程如下:
    W0 DIout,ARin
    W1 AR→AB,RD
    W2 MD→DB,DRin
    W3 DRout,Sin
    在此取操作数的周期结束时,就将以 DI 的内容为内存地址的存储器单元的内容读出并放在暂存器 S 中,其输出加到了 ALU 的一边,接着就进行下一步执行周期EXEC。

    ③ 转移指令
    在这里写出无条件转移和满足条件的条件转移的取操作数微操作命令安排。不
    满足条件顺序执行前面己经提到,这里不再说明。
    W0 PCout,ARin
    W1 AR→AB,RD,PC+1
    W2 MD→DB,DRin
    W3 DRout,Sin
    将指令操作数即偏移地址取出放入暂存器 S。

    ④ INC [BX]
    该指令的取操作数周期过程如下:
    W0 BXout,ARin
    W1 AR→AB,RD
    W2 MD→DB,DRin
    W3 DRout,Sin
    在此取操作数的周期结束时,就将以 BX 的内容为内存地址的存储器单元的内容读出并放在暂存器 S 中,其输出加到了 ALU 的一边,接着就启动下一步执行周期EXEC。

    ⑤ SHR CX
    该指令的取操作数周期过程如下:
    W0
    W1
    W2
    W3 CXout,Sin

    (3)执行周期(执行)EXEC

    ① MOV AX, 4000H
    该指令取指令操作数与执行周期合在一起,前面己经说明。

    ② ADD BX, [DI]
    该指令的执行周期过程如下:
    W0 S→ALU
    W1 BXout→ALU
    W2 ALU,ADD→T,Tin
    W3 Tout,BXin
    在此周期里,ALU 将放在 S 中的操作数与 BX 的内容相加送 T,T 输出放回 BX中。

    ③ 转移指令
    在这里写出无条件转移和满足条件的条件转移的执行周期微操作命令安排。
    W0 S→ALU,
    W1 PCout→ALU
    W2 ALU,ADD→T,Tin
    W3 Tout,PCin
    将 PC 的当前值与偏移地址相加,构成目的地址放 PC。

    ④ INC [BX]
    该指令的执行周期过程如下:
    W0 S→ALU
    W1 ALU+1→T,Tin
    W2 Tout,DRin
    W3 DR→DB,WR
    在此周期中,将上面周期取得的操作数经 ALU 加 1,再送到数据寄存器 DR 中。此时,AR 中仍存有操作数的地址,送时就将 DR 出的数据写回原来的地址,

    ⑤ SHR CX
    该指令的执行周期过程如下:
    W0 S→ALU
    W1 ALU 直通→T,Tin
    W2 T 逻揖右移一次
    W3 Tout,CXin

    ⑥ IRET
    中断返回指令由取指周期直接进入执行周期,其过程为:
    W0 SPout,ARin
    W1 AR→AB,RD,SP+1
    W2 MD→DB,DRin
    W3 DRout,PCin

    ⑦ 中断响应过程 INTA
    对中断请求响应时,CPU 仅保护 PC 的内容,并且由硬件提供该中断的中断向量。其过程为:
    W0 SPout,ARin
    W1 AR→AB,SP-1
    W2 PCout,DRin
    W3 DR→DB,WR
    W0 0→IF,IFin
    W1
    W2
    W3 IVout,PCin
    中断响应过程需两个机器周期,第 1 个机器周期保护断点 PC 的内容入堆栈。第 2 个机器周期关中断(使 IF=0),并将特定的该中断的中断向量 IV 放入 PC,并启动取指周期。则下一个机器周期 CPU 必定进入该中断的中断处理程序入口开始执行。

    六、例题

    1.搞清问题

    【问的是什么?微操作流程还是微流程】
    实现指令 ADD AX, BX(功能为(AX)+(BX)→AX )

    • 微操作流程:
      PC→AR
      AR→AB,RD,PC+1
      DB→DR
      DR→IR
      AX→S
      BX→IB,ADD
      ALU→T
      T→AX
    • 微流程:
      ① PCout,ARin
      ② AR→AB,RD,PC+1
      ③ MD→DB,DRin
      ④ DRout,IRin
      ⑤ BXout,ARin
      ⑥ AR→AB,RD
      ⑦ MD→DB,DRin
      ⑧ DRout,Sin
      ⑨ S→ALU
      ⑩ AXout→ALU
      11.ADD→T,Tin
      12.Tout,AXin

    【问的是哪些阶段?是所有阶段还是只写指令执行阶段】

    2.例题

    在这里插入图片描述

    (1)ADD指令

    将源操作数放入S中,再由S输入到ALU中
    将目的操作数直接输入到ALU中

    ADD AX, [BX]

    (取指)
    ① PCout,ARin
    ② AR→AB,RD,PC+1
    ③ MD→DB,DRin
    ④ DRout,IRin

    (将[BX]对应的储存器中的数取出,放到S中)
    ⑤ BXout,ARin
    ⑥ AR→AB,RD
    ⑦ MD→DB,DRin
    ⑧ DRout,Sin
    ⑨ S→ALU

    (将AX中的数取出,放到S中)
    ⑩ AXout→ALU

    (两数相加,并将结果放入AX)
    11.ADD→T,Tin
    12.Tout,AXin

    ADD BX, [DI]

    ① PCout,ARin
    ② AR→AB,RD,PC+1
    ③ MD→DB,DRin
    ④ DRout,IRin

    ⑤ DIout,ARin
    ⑥ AR→AB,RD
    ⑦ MD→DB,DRin
    ⑧ DRout,Sin
    ⑨ S→ALU

    ⑩ BXout→ALU

    11 ADD→T,Tin
    12 Tout,BXin

    ADD AX,DISP(SI)

    (取指)
    ① PCout,ARin
    ② AR→AB,RD,PC+1
    ③ MD→DB,DRin
    ④ DRout,IRin

    (计算偏移地址)
    ⑤ PCout,ARin
    ⑥ AR→AB,RD,PC+1
    ⑦ MD→DB,DRin
    ⑧ DRout,Sin
    ⑨ S→ALU

    ⑩ SIout→ALU

    11 ADD→T,Tin
    12 Tout,ARin

    (取内存中数)
    13 AR→AB,RD,
    14 MD→DB,DRin
    15 DRout,Sin
    16 S→ALU

    (将AX中的数取出,放到S中)
    16 AXout→ALU

    (两数相加,并将结果放入AX)
    17 ADD→T,Tin
    18 Tout,AXin

    (2)SUB BX,100(DI)

    ① PCout,ARin
    ② AR→AB,RD,PC+1
    ③ MD→DB,DRin
    ④ DRout,IRin

    ⑤ PCout,ARin
    ⑥ AR→AB,RD,PC+1
    ⑦ MD→DB,DRin
    ⑧ DRout,Sin
    S→ALU
    ⑨ DIout→ALU
    10 ADD→T,Tin
    11 Tout,ARin
    12 AR→AB,RD,
    13 MD→DB,DRin
    14 DRout,Sin
    15 S→ALU
    16 BXout→ALU
    17 SUB→T,Tin
    18 Tout,BXin

    (3)INC指令

    INC [BX]

    ① PCout,ARin
    ② AR→AB,RD,PC+1
    ③ MD→DB,DRin
    ④ DRout,IRin

    ⑤ BXout,ARin
    ⑥ AR→AB,RD
    ⑦ MD→DB,DRin
    ⑧ DRout,Sin
    ⑨ S→ALU

    ⑩ ALU+1→T,Tin
    11 Tout,DRin
    12 DR→DB,WR

    展开全文
  • 最近几天在学习IMAP协议,虽然网络上对IMAP介绍的资料不少,但是有关IMAP协议指令的资料很少,能让我这个新手研究明白的资料就更少了。刚开始学习的时候抱着官方的指导手册看,虽然已经翻译成了中文,但是那专业的...

    最近几天在学习IMAP协议,虽然网络上对IMAP介绍的资料不少,但是有关IMAP协议指令的资料很少,能让我这个新手研究明白的资料就更少了。刚开始学习的时候抱着官方的指导手册看,虽然已经翻译成了中文,但是那专业的描述,真的是晦涩难懂啊。怎么看,那东西都是属于文艺青年专有的,不是我这个普通青年能理解的东西。庆幸的是经过了我几天的东拼西凑,总算是把这个协议弄懂了六七成,现在可以做到用IMAP协议收发邮件了。下面就对这两天的学习做个小结。

    一旦客户端和服务器间的连接建立完成,一个IMAP4rev1连接就会处于4种状态中的某一种。
    1.未认证状态 :在未认证状态下,大多数命令在得到许可前,客户端必须提供认证证书。若非连接已经是预认证了的,一个连接开始时,就进入了未认证状态。
    2. 认证状态 :在认证状态下,客户端是认证了的,它必须先于影响邮件的命令被许可前,选择一个邮箱以访问。当一个预认证连接开始,被认可的认证证书已经提供,选择一个邮箱发生错误后,或者一个成功的CLOSE命令后,就进入了认证状态。
    3. 选中状态 :在一个选中状态,一个邮箱被选中以访问。当一个邮箱被成功选中时,就进入了这个状态。
    4. 注销状态 :在注销状态下,连接正在被终止。一个客户端请求(通过LOGOUT命令),或者客户端、服务器的单方面动作,都会导致进入这个状态。

    之所以提及到状态,是因为IMAP协议的很多指令只有在处于某种状态下才会有效。下面我就为大家罗列一下指令的作用的权限吧。

    1.在任何状态下都有效的指令(全局命令):CAPALIBILY,NOOP,LOGOUT。

    2.未认证状态下有效的指令(未认证状态命令):STARTTLS,AUTHENTICATE,LOGIN和全局命令。

    3.认证状态下有效的指令(认证状态命令):SELECT,EXAMINE,CREATE,DELETE,RENAME,SUBSCRIBE,UNSUBSCRIBE,LIST,LSUB,STATUS,APPEND和全局命令

    4.在选中状态下有效的指令(选中状态指令):CHECK,CLOSE,EXPUNGE,SEARCH,FETCH,STORE,COPY,UID和全局命令、认证状态命令。jie

    上面所说的基本上就是IMAP协议里的所有指令了。下面我将要介绍其中一部分我理解了的指令(这些指令就可以实现收取邮件了。)

    1.
    CREATE <folder>
    CREATE可以创建指定名字的新邮箱。邮箱名称通常是带路径的文件夹全名。(有些IMAP客户机使用邮件夹称呼新邮箱)
    C: A003 CREATE owatagusiam/ /*创建一个新目录owatagusiam*/
    S: A003 OK CREATE completed
    C: A004 CREATE owatagusiam/blurdybloop
    /* 在创建的目录owatagusiam下创建一个名为blurdybloop 的邮箱,当然可以省略第一步,直接A004 CREATE owatagusiam/blurdybloop ,表示在新的目录owatagusiam 下创建了一个名为blurdybloop 的邮箱*/
    S: A004 OK CREATE completed

    /**********IMAP协议发送指令有个不同于SMTP和POP协议的一个地方,就是指令全面必须要加一个4位标签,如A003,A004.这个标签有什么特别的意义我也不清楚。对于这个标签,你可以随便写也可以是“abcd”,"efgh",只要是保证是四位就可以了。可以重复,我多次试验,也没有发现重复了会带来什么问题。这个CREATE指令我也没有发送成功过,不知道为什么。如果有懂的朋友,希望指点一二。说这么多大家未必明白,举个例子就行了(后面我回贴上详细代码,大家一看便知了)。比如说要发送LOGOUT指令,发送过去的指令要写成这样"a001 logout\r\n",只有这样服务器才能识别。                                                                                                                                                      ************/

    2.
    DELETE <folder>
    DELETE命令删除指定名字的文件夹。文件夹名字通常是带路径的文件夹全名,当邮箱被删除后,其中的邮件也不复存在。
    C: A683 DELETE blurdybloop
    S: A683 OK DELETE completed
    C: A684 DELETE foo
    S: A684 NO Name "foo" has inferior hierarchical names
    C: A685 DELETE foo/bar
    S: A685 OK DELETE Completed

    3.
    RENAME <old folder><new folder>
    RENAME命令可以修改文件夹的名称,它使用两个参数:当前邮箱名和新邮箱名,两个参数的命名符合标准路径命名规则。
    C: A683 RENAME blurdybloop sarasoop
    S: A683 OK RENAME completed
    C: A684 RENAME stuff/junk newbox /*把stuff目录(文件夹)下的邮箱junk改名为newbox*/
    S: A684 OK RENAME Completed

    4.
    LIST <BASE><template>
    LIST命令用于列出邮箱中已有的文件夹,有点像操作系统的列目录命令,有两个参数,邮箱路径参数BASE:表示用户登陆目录;第二个参数template:表示希望显示的邮箱名。这个命令可以包含起始的路径位置和需要列出的文件夹所符合的特征,可以使用通配符"*"。
    C: A101 LIST "" ""
    S: * LIST (\Noselect) "/" ""
    S: A101 OK LIST Completed
    C: A102 LIST #news.comp.mail.misc ""
    S: * LIST (\Noselect) "." #news.
    S: A102 OK LIST Completed
    C: A103 LIST /usr/staff/jones ""
    S: * LIST (\Noselect) "/" /
    S: A103 OK LIST Completed
    C: A202 LIST ~/Mail/ %
    S: * LIST (\Noselect) "/" ~/Mail/foo
    S: * LIST () "/" ~/Mail/meetings
    S: A202 OK LIST completed

    5.
    APPEND <folder><attributes><date/time><size><mail data>
    APPEND命令允许Client上载一个邮件到指定的Folder(文件夹/邮箱)中。命令中包含了新邮件的属性、日期/时间、大小,随后是邮件数据。
    C: A003 APPEND saved-messages (\Seen) {310}
    C: Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)
    C: From: Fred Foobar <foobar@Blurdybloop.COM>
    C: Subject: afternoon meeting
    C: To: mooch@owatagu.siam.edu
    C: Message-Id: <B27397-0100000@Blurdybloop.COM>
    C: MIME-Version: 1.0
    C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
    C:
    C: Hello Joe, do you think we can meet at 3:30 tomorrow?
    C:
    S: A003 OK APPEND completed

    6.
    SELECT <folder>
    SELECT命令让Client选定某个邮箱(Folder),表示即将对该邮箱(Folder)内的邮件作操作。邮箱标志的当前状态也返回给了用户,同时返回的还有一些关于邮件和邮箱的附加信息。
    C: A142 SELECT INBOX
    S: * 172 EXISTS
    S: * 1 RECENT
    S: * OK [UNSEEN 12] Message 12 is first unseen
    S: * OK [UIDVALIDITY 3857529045] UIDs valid
    S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
    S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
    S: A142 OK [READ-WRITE] SELECT completed

    7.
    FETCH <mail id><datanames>
    FETCH 命令用于读取邮件的文本信息,且仅用于显示的目的。包含两个参数,messageset:表示希望读取的邮件号列表,IAMP服务器邮箱中的每个邮件都有 一个唯一的ID标识,(邮件号列表参数可以是一个邮件号,也可以是由逗号分隔的多个邮件号,或者由冒号间隔的一个范围),IMAP服务器返回邮件号列表中 全部邮件的指定数据项内容。
    数据名参数确定能够被独立返回的邮件的一部分,下面我们看看各参数返回的邮件信息:
    ALL:只返回按照一定格式的邮件摘要,包括邮件标志、RFC822.SIZE、自身的时间和信封信息。IMAP客户机能够将标准邮件解析成这些信息并显示出来。
    BODY:只返回邮件体文本格式和大小的摘要信息。IMAP客户机可以识别这些细腻,并向用户显示详细的关于邮件的信息。其实是一些非扩展的BODYSTRUCTURE的信息。
    FAST:只返回邮件的一些摘要,包括邮件标志、RFC822.SIZE、和自身的时间。
    FULL:同样的还是一些摘要信息,包括邮件标志、RFC822.SIZE、自身的时间和BODYSTRUCTURE的信息。
    BODYSTRUCTURE: 是邮件的[MIME-IMB]的体结构。这是服务器通过解析[RFC-2822]头中的[MIME-IMB]各字段和[MIME-IMB]头信息得出来 的。包括的内容有:邮件正文的类型、字符集、编码方式等和各附件的类型、字符集、编码方式、文件名称等等。
    ENVELOPE:信息的信封结构。是服务器通过解析[RFC-2822]头中的[MIME-IMB]各字段得出来的,默认各字段都是需要的。主要包括:自身的时间、附件数、收件人、发件人等。
    FLAGS:此邮件的标志。
    INTERNALDATE:自身的时间。
    RFC822.SIZE:邮件的[RFC-2822]大小
    RFC822.HEADER:在功能上等同于BODY.PEEK[HEADER],
    RFC822:功能上等同于BODY[]。
    RFC822.TEXT:功能上等同于BODY[TEXT]
    UID:返回邮件的UID号,UID号是唯一标识邮件的一个号码。
    BODY[section] <<partial>>:返回邮件的中的某一指定部分,返回的部分用section来表示,section部分包含的信息通常是 代表某一部分的一个数字或者是下面的某一个部分:HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT。如果section部分是空的话,那就代表返回全部的信息,包括头信息。
    BODY[HEADER]返回完整的文件头信息。
    BODY[HEADER.FIELDS ()]:在小括号里面可以指定返回的特定字段。
    BODY[HEADER.FIELDS.NOT ()]:在小括号里面可以指定不需要返回的特定字段。
    BODY[MIME]:返回邮件的[MIME-IMB]的头信息,在正常情况下跟BODY[HEADER]没有区别。
    BODY[TEXT]:返回整个邮件体,这里的邮件体并不包括邮件头。
    现在我们遇到了一个问题,如果我们要单独提取邮件的附件怎么办?
    通过以上的命令我们是无法做到的,但是我们别忘了在section部分还有其他的方式可以来表示我们要提取的邮件的部分,那就的通过区段数来表示。那下面就让我们来看看什么是区段数。
    每 个邮件都至少有一个区段数,Non-[MIME-IMB]型的邮件和non-multipart [MIME-IMB]的邮件是没有经过MIME编码之后的信息的,那这样的信息只有一个区段数1。多区段型的信息被编排成一个连续的区段数,这和实际信息 里出现的是一样的。如果一个特定的区段有类型信息或者是多区段的,一个MESSAGE/RFC822类型的区段也含有嵌套的区段数,这些区段数是指向这些 信息区段的信息体的。
    说了那么多拗口的,现在我们讲的更简单易懂一些。在一个邮件体里面,区段数1代表的邮件的正文,区段数二代表的是第一个附 件,区段数三代表的是第二个附件,以此类推。在这些区段里,如果有哪个区段又是多区段的,比如2区段的内容格式是mulipart或者是 MESSAGE/RFC822类型的,那么这个区段又嵌套了多个子区段,嵌套的各子区段是用2.1,2.2……等等表示,类似,如果2.1又有嵌套,那么 还会有2.1.1,2.1.2等区段。这样的嵌套是没有限制的。下面我们通过例子来了解一下fetch具体是怎么按区段下载的。
    HEADER ([RFC-2822] header of the message)
    TEXT ([RFC-2822] text body of the message) MULTIPART/MIXED
    1 TEXT/PLAIN
    2 APPLICATION/OCTET-STREAM
    3 MESSAGE/RFC822
    3.HEADER ([RFC-2822] header of the message)
    3. TEXT ([RFC-2822] text body of the message) MULTIPART/MIXED
    3.1 TEXT/PLAIN
    3.2 APPLICATION/OCTET-STREAM
    4 MULTIPART/MIXED
    4.1 IMAGE/GIF
    4.1. MIME ([MIME-IMB] header for the IMAGE/GIF)
    4.2 MESSAGE/RFC822
    4.2. HEADER ([RFC-2822] header of the message)
    4.2. TEXT ([RFC-2822] text body of the message) MULTIPART/MIXED
    4.2.1 TEXT/PLAIN
    4.2.2 MULTIPART/ALTERNATIVE
    4.2.2.1 TEXT/PLAIN
    4.2.2.2 TEXT/RICHTEXT
    如果我们需要取第一个附件,那么命令就是:
    C:a2 fetch 4 body[2];
    取第三个区段的第一个子区段文本正文,命令就是:
    C:a2 fetch 4 body[3.1];
    取第四个区段的第二个子区段再嵌套的第一个子区段的文本正文,命令如下:
    C:a2 fetch 4 body[4.2.1]
    当然这个例子只是针对于一个特殊的邮件结构,一般的邮件应该都没有这么复杂的结构。
    再 接下来我们再看看最后一个参数有什么用?BODY[section]可以使用partial字段进行修改,该字段包含两个用“.”隔开的数字,第一个数 字、是八进制表示的希望显示的数据输出起始位置,第二个数字是八进制表示希望显示的数据长度。这项功能可以进一步设定输出格式,例如,如果你希望显示1号 邮件中邮件提的前1500个字符,可以使用命令:
    FETCH 1 BODY[TEXT]<0.1500>
    该命令取回邮件提的前1500个字符并定义为TEXT,如果邮件体少于1500个字符则返回整个邮件体。
    例:
    C: 100 FETCH 3:5 BODY[header.fields (Date From Subject)] /*冒号表示间隔的一个范围:请求邮件从3到5之间所有邮件的Date:字段、 From:字段和 Subject:字段的信息*/
    S: * 3 FETCH (BODY[HEADER.FIELDS (“DATE” “FROM” “SUBJECT”)] {112}
    DATE: Tue, 14 Sep 1999 10:09:50 -500
    From: alex@shadrach.smallorg.org
    Subject: This is the first test message
    )
    S: * 4 FETCH (BODY[HEADER.FIELDS (“DATE” “FROM” “SUBJECT”)] {113}
    DATE: Tue, 14 Sep 1999 10:10:04 -500
    From: alex@shadrach.smallorg.org
    Subject: This is the second test message
    )
    S: * 5 FETCH (BODY[HEADER.FIELDS (“DATE” “FROM” “SUBJECT”)] {112}
    DATE: Tue, 14 Sep 1999 10:20:26 -500
    From: alex@shadrach.smallorg.org
    Subject: This is the first test message
    S: A100 OK FETCH completed
    C: A101 FETCH BODY[TEXT]
    S:* This is the fourth test message for IMAP
    S: A101 OK FETCH completed
    FETCH命令是IMAP协议里最复杂的命令。FETCH的命令参数很多、很复杂,但基本的特征是允许将邮件按照MIME结构拆解为零碎的部件来提取。例如,可以利用FETCH命令提取邮件头、某一个附件、或某一邮件附件头部的某一字段,等等。
    BODY.PEEK [<section>] <<partial>>:
    在 缺省设置时,宏BODY[<section>]<<partial>>会设置邮件的\SEEN标志。如果你想在不设 置\SEEN标志的情况下阅读邮件的部分信息,那么可以将该宏替代BODY .PEEK[section],后者完成同前者一样的功能但不会设置该邮件的\SEEN标志。

    8.
    STORE <mail id><new attributes>
    STORE 命令用于修改指定邮件的属性,包括给邮件打上已读标记、删除标记,等等。STORE命令当前只有两个数据项类型可用,FLAGS:表示邮件的一组标志; FLAGS.SLIENT,表示一组邮件的标志,通过在两种数据项前加上加号或者减号可以进一步改变它们的执行情况,加号表示数据项的值添加到邮件中,减 号表示将数据项的值从邮件中删除。
    C: A003 STORE 2:4 +FLAGS (\Deleted) /*冒号表示间隔的一个范围:给从2到4的邮件设置Deleted属性*/
    S: * 2 FETCH FLAGS (\Deleted \Seen)
    S: * 3 FETCH FLAGS (\Deleted)
    S: * 4 FETCH FLAGS (\Deleted \Flagged \Seen)
    S: A003 OK STORE completed


    /********经过多次尝试,store指令要让服务器识别,发送的字符串需要这样写:“A003 STORE 2 +FLAGE(\\Deleted\r\n)”(因为我用的是C++,所以需要两个“\”,一个在编译时候会报错的).不同于别的指令的地方,这个指令需要于“)”结束,所以“\r\n”不能放在最后,而是要放在“()”里面去                                                  ****************/


    9.
    CLOSE
    CLOSE命令表示Client结束对当前Folder(文件夹/邮箱)的访问,关闭邮箱该邮箱中所有标志为、DELETED的邮件就被从物理上删除。CLOSE没有命令参数。随后可以SELECT另一Folder。
    C: A341 CLOSE
    S: A341 OK CLOSE completed

    10.
    EXPUNGE
    EXPUNGE命令在不关闭邮箱的情况下删除所有的标志为、DELETED的邮件。EXPUNGE删除的邮件将不可以恢复。
    C: A202 EXPUNGE
    S: * 3 EXPUNGE
    S: * 3 EXPUNGE
    S: * 5 EXPUNGE
    S: * 8 EXPUNGE
    S: A202 OK EXPUNGE completed
    LOGOUT
    LOGOUT命令结束本次IMAP会话。
    C: A023 LOGOUT
    S: * BYE IMAP4rev1 Server logging out
    S: A023 OK LOGOUT completed
    (Server and client then close the connection)

    11.
    EXAMINE <mailbox>
    EXAMINE命令以只读方式打开邮箱,参数是需要打开的邮箱的名字,使用EXAMINE命令打开的邮箱不允许对邮件进行改动,因此不能增加或删除邮件的标志。

    12.
    SUBSCRIBE <mailbox>
    SUBSCRIBE命令用来在客户机的活动邮箱列表中增加一个邮箱,该命令只有一个参数,希望添加的邮箱名。
    C: A114 SUBSCRIBE new/anotherbox
    S: A114 OK SUBSCRIBE completed

    13.
    UNSUBSCRIBE <mailbox>
    UNSUBSCRIBE命令用来从活动列表中去掉一个邮箱,一个参数:希望去掉的邮箱名。
    C: A115 UNSUBSCRIBE new/anotherbox
    S: A115 OK SUBSCRIBE completed

    14.
    LSUB <folder><mailbox>
    LSUB命令修正了LIST命令,LIST返回用户$HOME目录下所有的文件,但LSUB命令只显示那些使用SUBSCRIBE命令设置为活动邮箱的文件。两个参数:邮箱路径和邮箱名。
    C: A116 LSUB “” *
    S:* LSUB () “/” stuff/junk
    S:* LSUB () “/” neebox
    S:* LSUB () “/” new/anotherbox
    S: A116 OK LSUB completed

    15.
    STATUS <mailbox>(<parameter1> < parameter2> ……<parameter5>)
    STATUS命令查询邮箱的当前状态。第一个参数是需要查询的邮箱名,第二个参数是客户机需要查询的项目列表(要查询显示的信息),当在圆括号中。STATUS可以在不使用SELECT命令(打开邮箱)或者EXAMINE(以只读方式打开邮箱)前提下获取邮箱的信息。
    STATUS命令可以获得的数据项
    项 目 说 明
    MESSAGE 邮箱中的邮件总数
    RECENT 邮箱中标志为\RECENT的邮件数
    UIDNEXT 可以分配给新邮件的下一个UID
    UIDVALIDITY 邮箱的UID有效性标志
    UNSEEN 邮箱中没有被标志为\UNSEEN的邮件数
    C: A117 STATUS inbox (message recent unseen)
    S:* STATUS inbox (MESSAGE 1 RECENT 0 UNSENN 0)
    S: A117 OK STATUS completed
    C: A118 STATUS newbox (message recent unseen)
    S:* STATUS inbox (MESSAGE 1 RECENT 0 UNSENN 2)
    S: A118 OK STATUS completed

    16.
    CHECK
    CHECK命令用来在邮箱设置一个检查点。没有参数。就是IMAP中的sync命令。任何未完成的操作,例如从服务器内存向硬盘写数据,都将会被做完以保持邮箱的一致性状态。该命令确保乃村中的磁盘缓冲数据都被写到了磁盘上。

    17.
    SEARCH [CHARSET specification] (search criteria)
    命 令可以根据搜索条件在处于活动状态的邮箱中搜索邮件,然后显示匹配的邮件编号。字符集标志参数[CHARSET specification]由CHARSET和注册的字符集标志符组成,缺省的标志符是US-ASCⅡ,所以该参数长省略。search criteria:查询条件参数,明确查询的关键字和值。查询关键字有几十种。
    C: A119 SEARCH header subject another
    S: SEARCH 1 2
    S:* A119 OK SEARCH completed
    C: A120 SEARCH header subject another
    S: *SEARCH 2
    S: A120 OK SEARCH completed
    C: A121 SEARCH UNSEEN
    S: *SEARCH 1 2
    S: A120 OK SEARCH completed
    以上每个例子都在邮件头的Subject:字段中查询一个不同的单词。服务器返回条件的邮件号列表,如果没有匹配邮件则返回不带UID的SEARCH单词。

    18.
    COPY <mail id><mailboxname>
    COPY命令可以把邮件从一个邮箱复制到另一个邮箱,两个参数:mail id是希望从活动邮箱中复制的邮件的标号,mailboxname是希望邮件被复制到的邮箱。
    IAMP没有定义移动邮件的命令,移动操作相当于先把邮件复制到新邮箱中,然后对源邮箱中的邮件设置\DELETED标志。下一次执行检查点过后,新邮箱中的邮件被删除,新邮件就被显示出来。

    19.
    UID
    UID 命令和FETCH、COPY、STORE命令或者SEARCH命令一起使用,它允许这些命令使用邮件的UID号而不是在邮箱中的顺序号。UID号是唯一标 识邮件系统中邮件的32位证书。通常这些命令都使用顺序号来标识邮箱中的邮件,使用UID可以使IMAP客户机记住不同IMAP会话中的邮件。

    20.
    CAPABILITY
    CAPABILITY命令请求返回IMAP服务器支持的功能列表,服务器收到客户机发送的CAPABILITY命令后将返回该服务器所支持的功能。无参数。
    C: A122 CAPABILITY
    S:*A122 CAPABILITY IMAP4 IMAP4REVl NAMESPACE IDLE SCAN SORT MAILBOX
    --REFERRALS [ic:ccc] LOGIN-REFERRALS AUTH=LOGIN THREAD=
    ORDERDSUBJECT
    S: A122 OK CAPABILITY completed

    21.
    NOOP
    NOOP命令什么也不做,用来向服务器发送自动命令,防止因长时间处于不活动状态而导致连接中断,服务器对该命令的响应始终为肯定。无参数。

    22.
    LOGOUT
    LOGOUT命令使当前登陆用户退出登陆并关闭所有打开的邮箱,任何做了\DELETED标志的邮件都将在这个时候被删除。

    再次重申一下:这里不是所有的命令都列出来了,没有列出来的命令如果需要的可以去参考RFC3501。

    下面我把我的代码给贴出來给大家参考一下(实现了接收邮件的功能)

    sock.h文件

    1 #ifndef __SOCK_H__
      2 #define __SOCK_H__
      3 
      4 #include <iostream>
      5 #include <sys/socket.h>
      6 #include <sys/epoll.h>
      7 #include <stdio.h>
      8 #include <netinet/in.h>
      9 
     10 class Sock
     11 {
     12     public:
     13         Sock();
     14         bool Connect(const char *host_id, const int &port);
     15         void send_socket(const char *s);
     16         int recv_socket();
     17         const char * get_recvbuf();
     18         ~Sock();
     19         private:
     20         char recvbuf[BUFSIZ];
     21         int sock;
     22         int num;
     23         struct sockaddr_in server;
     24         struct hostent *hp;
     25 };
     26 
     27 #endif
    

    sock.cpp文件

    1 #include "sock.h"
      2 #include <stdexcept>
      3 #include <netdb.h>
      4 #include <string.h>
      5 #include <sys/types.h>
      6 
      7 Sock::Sock()
      8 {
      9     sock = socket(AF_INET, SOCK_STREAM, 0);
     10     if(sock == -1)
     11     {
     12         throw std::runtime_error("socket init error\n");
     13     }
     14 }
     15 Sock::~Sock()
     16 {
     17     close(sock);
     18 }
     19 bool Sock::Connect(const char *host_id, const int &port)
     20 {
     21     server.sin_family = AF_INET;
     22     hp = gethostbyname(host_id);
     23     if(hp == (struct hostent *) 0)
     24     {
     25         std::cerr << "服务器地址获取失败!" << std::endl;
     26         return false;
     27     }
     28     memcpy((char *)&server.sin_addr,
     29             (char *)hp->h_addr, hp->h_length);
     30     server.sin_port = htons(port);
     31     if(connect(sock, (sockaddr *) &server, sizeof server) == -1)
     32     {
     33         std::cerr << "连接服务器失败!" << std::endl;
     34         return false;
     35     }
     36     else
     37         return true;
     38 }
    
     void Sock::send_socket(const char *s)
     40 {
     41     send(sock, s, strlen(s), 0);
     42 }
     43 int Sock::recv_socket()
     44 {
     45     memset(recvbuf, 0,BUFSIZ);
     46     return recv(sock, recvbuf, BUFSIZ, 0);
     47 }
     48 const char * Sock::get_recvbuf()
     49 {
     50     return recvbuf;
     51 }
    

    imapmain.cpp文件

     1 #include "sock.h"
      2 #include <iostream>
      3 #include <string.h>
      4 #include <string>
      5 
      6 int main()
      7 {
      8     Sock sock;
      9     const char *host_id = "imap.126.com";
     10     int port = 143;
     11     if(sock.Connect(host_id, port) == false)
     12         return 1;
     13     std::cout << "connected\n";
     14     sock.recv_socket();
     15     std::cout << "Client : connect successfully \nServer :"
     16         << sock.get_recvbuf() << std::endl;
     17     sock.send_socket("a001 capability\r\n");
     18     sock.recv_socket();
     19     std::cout << "Client : send capability \nServer :"
     20         << sock.get_recvbuf() << std::endl;
     21 
     22 
     23     sock.send_socket("a002 noop\r\n");
     24     sock.recv_socket();
     25     std::cout << "Client : send noop \nServer : "
     26         << sock.get_recvbuf() << std::endl;
     27 
     28     sock.send_socket("a005 login username password\r\n");
     29     sock.recv_socket();
     30     std::cout << "Client : send login \nServer : "
     31         << sock.get_recvbuf() << std::endl; 
     32         
     33     sock.send_socket("a007 select inbox\r\n");
     34     sock.recv_socket();
     35     std::cout << "Client : send search \nServer : "
     36         << sock.get_recvbuf() << std::endl; 
     37         
    
    38     sock.send_socket("a008 list \".\" #news\r\n");
     39     sock.recv_socket();
     40     std::cout << "Client : send list \nServer : "
     41         << sock.get_recvbuf() << std::endl;
     42 
     43     sock.send_socket("a009 search all\r\n");
     44     sock.recv_socket();
     45     std::cout << "Client : send search \nServer : "
     46         << sock.get_recvbuf() << std::endl;
     47 
     48     sock.send_socket("a010 fetch 5 full\r\n");
     49     sock.recv_socket();
     50     std::cout << "Client : send fetch \nServer :"
     51         << sock.get_recvbuf() << std::endl;
     52 
     53     sock.send_socket("a011 fetch 5 body[header]\r\n");
     54     sock.recv_socket();
     55     std::cout << "Client : send fetch\nServer :"
     56         << sock.get_recvbuf() << std::endl;
     57 
     58     sock.send_socket("0012 fetch 5 body[text]\r\n");
     59     sock.recv_socket();
     60     std::cout << "Client : send fetch body[text]\n Server :"  //这里接收会有个问题,应该是用个循环接收,但是我不知道怎么判断接收完毕,所以就...
     61         << sock.get_recvbuf() << std::endl;
     62 
     63     sock.send_socket("a013 logout\r\n");
     64     sock.recv_socket();
     65     std::cout << "Client : send logout\nServer :"
     66         << sock.get_recvbuf() << std::endl;
     67 }
    


    参考资料链接:点击打开链接

    展开全文
  • 菜鸟学汇编003 代码段寄存器 CS 和 指令指针寄存器 IP 分类: 菜鸟学汇编2010-10-20 21:18 992人阅读 评论(0) 收藏 举报 1. 8086CPU有20位地址总线,可以传送20位的地址,达到1MB寻址能力。  ...
     

    菜鸟学汇编003 代码段寄存器 CS 和 指令指针寄存器 IP

    分类: 菜鸟学汇编   992人阅读  评论(0)  收藏  举报

    1. 8086CPU有20位地址总线,可以传送20位的地址,达到1MB寻址能力。

        而 8086CPU 是16位结构,在内部一次性处理、传输、暂时存储的地址都是16位,

        从内部结构看,寻址能力只有64KB。

     

        怎么办呢? 在8086CPU内部使用2个16位的地址来合成一个20位的物理地址。

     

    2. 段寄存器有4个:CS、DS、SS、ES。 我们先来看学习 代码段寄存器CS 。

     

    3. 段地址(16位) + 偏移地址(16位) ---->送到 “地址加法器”, 传出来后就是 20位的物理地址。

     

        物理地址 = 段地址 X 16 + 偏移地址

     

        例如 8086CPU要访问 123C8H的内存单元。

     

        段地址为1230H, 偏移地址为 00C8H。

        地址加法器 先把 段地址X16,段地址变成了12300H

        再进行小学学过的加法运算。

        12300H

                       +

          00C8H

    -----------------

        123C8H

     

    4. 段地址X16,可以理解为 左移4位, 一个X进制的数据左移一位,想当于原数据乘以X。

     

    5. 段地址X16 + 偏移地址 = 物理地址 的本质含义

        CPU在访问内存时,用一个基础地址(段地址X16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。

     

    6. CPU 可以用不同的段地址和偏移地址形成同一个物理地址。

     

    7. 如果给定一个段地址,仅通过变化偏移地址来进行寻址,最多可以定位64KB个内存单元。

     

    8. 在8086PC机中,存储单元的地址用2个元素来描述,段地址和偏移地址

     

    9. 段寄存器(CS、DS、SS、ES)中的CS段寄存器

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

        CS为代码段寄存器 (Code Segment Register) IP为指令指针寄存器 (Instruction Pointer Register) 


        在8086PC机中,任意时刻,设CS中的内容为M, IP中的内容为N,

        8086CPU将从内存 M X 16 + N 单元开始,读取一条指令并执行。

     

    10.  修改CS、IP的指令。

     

          大部分8086CPU寄存器的值,都可以使用mov指令来改变,mov指令被称为 传送指令

         

          mov指令不能修改CS、IP中的值,因为8086CPU没有提供这样的功能。

     

          能够改变CS、IP寄存器内容的指令称为 转移指令 

     

         一个最简单的可以修改CS、IP寄存器中值的指令:jmp 指令. 

     

         (1) 如果仅想修改IP寄存器的内容,语法如下:

         jmp 某一合法寄存器 ----> 用(某一合法)寄存器中的内容修改IP寄存器中的值。

     

         例子: 假设现在 ax = 1000H, CS = 2000H, IP = 0003H

         执行 jmp ax 后, ax = 1000H, CS = 2000H, IP = 1000H

     

         (2) 如果想同时修改CS:IP寄存器的值。可以使用语法: jmp 段地址:偏移地址

     

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

     

    11. 代码段:我们可以将长度为N(N <= 64KB)的一组代码,存在一组地址连续、起始地址为16倍数的内存单元中,

          我们可以认为,这段内存是用来存放代码的,从而定义了一个代码段。

     

          如果想让CPU执行到代码段中的指令,必须要将CS:IP指向所定义代码段中第一条指令的首地址。

     

          例如:以下代码段(长度为10个字节)

          mov ax, 0000H    (B8 00 00)

          add ax, 0123H    (05 23 01)

          mov bx, ax          (8B D8)

          jmp bx                (FF E3)

     

          如果把上面的代码段存放在 123B0H~123B9H内存单元中,将其定义为代码段,

          如果想让这段代码得到执行,可设CS=123BH,IP=0000H。

     

    12. 8086CPU的工作过程:

          

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

          (2) IP指向下一条指令

          (3) 执行指令 [然后重复步骤(1), 重复这个过程]

     

    展开全文
  • 模态指令和非模态指令

    万次阅读 2012-11-29 17:16:50
    模态指令一经程序段中指定,便一直有效,直到出现同组另一指令或被其他指令取消时才失效,与上一段相同的模态指令可省略不写。  非模态指令:非续效指令,仅在出现的程序段中有效,下一段程序需要时必须重写(如...
  • 8月13日,银河麒麟操作系统V10正式发布,其最大亮点就是专门对于国内自主研发的龙芯、...无独有偶同样也是8 月 13 日的全国计算机体系结构学术年会(ACA2020)上,龙芯中科董事长胡伟武作了名为《指令系统的自主与兼..
  • JVM之指令重排分析

    万次阅读 多人点赞 2016-08-08 15:49:28
    引言:在Java中看似顺序的代码在JVM中,可能会出现编译器或者CPU对这些操作指令进行了重新排序;在特定情况下,指令重排将会给我们的程序带来不确定的结果....
  • 指令系统

    千次阅读 2015-04-24 10:33:51
    计算机的操作和控制是由计算机的指令完成的。在计算机中有两种信息流,一种是数据流,它是处理的对象;一种是控制流,由它来对控制对数据信息的处理。 一、指令系统的发展   计算机的程序是由一系列的指令组成的...
  • 4.2 内存访问指令寻址 根据内存访问指令的分类,内存访问指令的寻址方式可以分为以下几种。 ① 字及无符号字节的Load/Store指令的寻址方式。 ② 杂类Load/Store指令的寻址方式。 ③ 批量Load/Store指令...
  • 准备功能也叫G功能或G代码。它是使数控机床或数控系统建立起某种加工方式的指令。G代码由地址符G和其后面的两位数字组成,从G00~G99共100种。...字母相同的为一组,同组的任意两个G代码不能同时出现在一个程序段中。
  • ARM 处理器的指令集可以分为 跳转指令、数据处理指令、程序状态寄存器(PSR)处理指令、加载/存储指令、协处理器指令和异常产生指令 六大指令,这里把其它几个指令一起发了出来,可以查看具体的目录,请点击头部左上...
  • 深度理解“指令集”

    万次阅读 多人点赞 2017-07-29 01:33:58
    指令顾名思义就是用来引导某一硬件工作的方式的,集即集合的意思,也就是很多种不同引导指令的集合!... 其实指令集就是一汇编指令的集合,不同的CPU使用的指令集不同。 过去比较常用的是lntel的X86C
  • 指令入门

    千次阅读 2016-10-22 22:48:23
     花指令是对抗反汇编的有效手段之一,正常代码添加了花指令之后,可以破坏静态反汇编的过程,使反汇编的结果出现错误。错误的反汇编结果会造成破解者的分析工作大量增加,进而使之不能理解程序的结构和算法,也就很...
  • 抗去除花指令(一)——花指令基础

    千次阅读 2015-01-04 13:22:53
    指令是对抗反汇编的有效手段之一,正常代码添加了花指令之后,可以破坏静态反汇编的过程,使反汇编的结果出现错误。错误的反汇编结果会造成破解者的分析工作大量增加,进而使之不能理解程序的结构和算法,也就很难...
  • Thumb指令

    千次阅读 2018-08-23 10:28:11
    Thumb指令集是ARM指令集的一个子集,是针对代码密度问题而提出的,它具有16位的代码宽度。与等价的32位代码相比较,Thumb指令集在保留32位代码优势的同时,大大的节省了系统的存储空间。Thumb不是一个完整的体系结构...
  • 01Linux常用指令

    万次阅读 多人点赞 2021-09-26 15:00:03
    所有的指令不要强制记忆,选项要多多查一下,多多练习使用即可。 文章目录一、Linux简单介绍1.1.Linux的目录结构1.2.常见的具体目录结构/bin/sbin/root/lib/etc/usr/boot/tmp/dev/media/mnt/opt/usr/local/var1.3....
  • java同步方法和同步代码

    万次阅读 多人点赞 2017-01-18 14:45:38
     一、当两个并发线程访问一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。  
  • Class字节码指令解释执行

    千次阅读 2017-09-17 16:00:19
    JVM指令主要包含了一下几种类型:加载和存储指令、运算指令、类型转换指令、对象创建与访问指令、操作数栈管理指令、控制转移指令、方法调用和返回指令、异常处理指令、同步指令等。 基于栈的解释器执行过程  下面...
  • CPU指令集介绍

    千次阅读 2020-09-13 11:21:49
    (1)什么是指令集 参考: http://product.pconline.com.cn/itbk/bjbzj/notebook/1109/2522116.html 所谓指令集,就是CPU中用来计算和控制计算机系统的一套指令的集合,而每一种新型的CPU在设计时就规定了一系列...
  • 计算机指令就是指挥机器工作的指示和命令,程序就是一系列按一定顺序排列的指令,执行程序的过程就是计算机的工作过程。通常一条指令包括两方面的内容: [1]操作码和操作数,操作码决定要完成的操作,操作数指参加...
  • mips指令

    千次阅读 2015-06-24 13:00:40
    MIPS指令特点: 1、所有指令都是32位编码; 2、有些指令有26位供目标地址编码;有些则只有16位。因此要想加载任何一个32位值,就得用两个加载指令。16位的目标地址意味着,指令的跳转或子函数的位置必须在64K以内...
  • CPU的指令集(指令系统)

    万次阅读 2019-02-06 20:00:09
    CPU的指令集(指令系统)
  • ZPL指令

    万次阅读 2015-03-11 16:14:38
    ^CC,~CC 改变格式指令前缀  ^CC,~CC(改变脱字符)指令是用于改变指令前缀。缺省前缀是脱字符(^)。 ^CC,~CC指令格式  ^CCx,~CCx ^CC,~CC = 改变脱字符 x = 任何...
  • 汇编伪指令总结

    千次阅读 2012-08-14 11:25:40
    汇编伪指令总结 段定义伪指令    段定义伪指令是表示一个段开始和结束的命令,80x86有两种段定义的方式:完整段定义和简化段定义,分别使用不同的段定义伪指令来表示各种段。  1 完整的段定义伪指令  ...
  • 带你走近AngularJS - 创建自定义指令

    千次阅读 2014-05-16 10:48:52
    使用过 AngularJS 的朋友应该最感兴趣的是它的指令。现今市场上的前端框架也只有...但是开发人员在使用Booostrap中的插件时, 必须切换到JavaScript 模式来写 jQuery 代码来激活插件虽然jQuery 代码写起来十分简
  • 电路比较简单,图如下 ALU 算术逻辑单元(arithmetic and logic unit) 是能实现多算术运算和逻辑运算的组合逻辑电路。 大部分ALU都可以完成以下运算∶ 1、整数算术运算(加、减,有时还包括乘和除,不过成本较高) ...
  • 代码的写法

    万次阅读 多人点赞 2016-12-09 14:24:06
    代码(Pseudocode)是一种算法描述语言。使用伪代码的目的是为了使被描述的算法可以容易地以任何一种编程语言(Pascal,C,Java,etc)实现。因此,伪代码必须结构清晰、代码简单、可读性好,并且类似自然语言。 ...
  • ARM 汇编指令

    万次阅读 多人点赞 2016-02-23 22:35:00
    ARM处理器的指令集可以分为跳转指令、数据处理指令、程序状态寄存器(PSR)处理指令、加载/存储指令、协处理器指令和异常产生指令6大指令。   一、 跳转指令  跳转指令用于实现程序流程的跳转,在ARM程序中有...
  • 目的:CRITICAL指令指定一块同一时间只能被一条线程执行的代码区域注意:如果一条线程正在一个CRITICAL区域执行而另一个线程到达这个区域,并企图执行,那么它将会被阻塞,直到第一个线程离开这个区域.命名是可选项,...
  • volatile与lock前缀指令

    万次阅读 多人点赞 2016-08-17 23:48:51
    为什么加上lock指令后就能保证volatile关键字的内存可见性。 lock指令的几个作用: 锁总线,其它CPU对内存的读写请求都会被阻塞,直到锁释放,不过实际后来的处理器都采用锁缓存替代锁总线,因为锁总线的开销比较大...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 203,505
精华内容 81,402
关键字:

同组指令代码