精华内容
下载资源
问答
  • Binary(2) Octal(O) Decimal(D) Hexadecimal(H) Ⅱ.二进制与十进制之间转化 Lesson 2 微处理结构 Ⅰ.计算机中多字节数据存储 小端存储:高高低低(高地址存高字节) Ⅱ.算术运算与逻辑运算 Ⅲ.补码运算...

    Lesson 1 微型计算机原理

    Ⅰ.各种进制

      Binary(2) Octal(O) Decimal(D) Hexadecimal(H)

    Ⅱ.二进制与十进制之间的转化

     

    Lesson 2 微处理结构

    Ⅰ.计算机中多字节数据的存储

    小端存储:高高低低(高地址存高字节)

    Ⅱ.算术运算与逻辑运算

    Ⅲ.补码的运算

    原码:首位为符号位 其余位为绝对值

    反码:正数=原码 负数=符号位(1)+按位取反

    补码:正数=原码 反码+1

    n位补码的表数范围:-2^{n-1}\leq N\leq 2^{n-1}-1

    (1000 0000 - 0111 1111)

    为什么最小的数是1000 0000?

    按照道理来说 +0 和 -0在补码表示法中都为0000 0000,而1000 0000在补码表示中什么也不代表,由于在无符号数中1000 0000代表128,所以将1000 0000表示为-128,因为符号位为1。

     

    Lesson 3

    Ⅰ.8086内部寄存器

    8086内部寄存器有:

    • 8个通用寄存器
    • 4个段寄存器
    • 1个指令指针寄存器
    • 1个标志寄存器

    Ⅱ.通用寄存器

    CPU在完成数据加工时临时存放数据(执行单元)

    前四个数据寄存器可以分成高8位和低8位两个独立的寄存器 对其中某8位的操作并不影响另外对应8位的数据

     AX BX CX DX(16位)

    (AH AL BH BL CH CL DH DL

     SI DI BP SP (8位)

    Ⅲ.段寄存器

    DS 数据段寄存器(Data Segment)

    CS 代码段寄存器(Code Segment)

    ES 附加段寄存器(Extra Segment)

    SS 堆栈段寄存器(Stack Segment)

    用于CPU在计算20位的物理地址的时候,其中一部分的数据来源

    这些段寄存器的内容与有效的地址一起,用于确定内存的物理地址。通常用DS确定数据段的基地址,CS确定代码段的基地址,ES确定附加段的基地址,SS确定堆栈段的基地址。

    Ⅳ.指令指针IP

    • 用于指示CPU下一条指令的偏移地址(总线接口)
    • IP与CS联用,确定下一条指令的物理地址,控制指令序列的执行流程
    • IP寄存器是一个专用的寄存器

    Ⅴ.标志寄存器FLAG

    标志寄存器反应指令的结果或者控制指令的形式

    标志的分类

    状态标志:用来记录程序运行的状态信息,许多指令的执行都将相应地设置它。

    • CF(Carry Flag):进位标志 CF=1有进位 CF=0无进位
    • ZF(Zero Flag):零标志 ZF=1表示为零 
    • SF(Sign Flag):符号标志 SF=1表示运算结果为负数
    • PF(Parity Flag):奇偶标志 PF=1表示低8位有偶数个1
    • OF(Overflow Flag):溢出标志 OF=1 表示有符号数运算产生溢出 怎么判断两个数相加是否溢出:最高位进位⊕次高位进位=1则溢出
    • AF(Auxiliary Flag):辅助进位标志 AF=1表示低4位有进位或者借位

    控制标志:可由程序根据需要用指令设置,用于控制处理器执行指令的方式。

    • DF(Direction Flag):方向标志 DF=1操作地址递减 DF=1表示操作地址递增
    • IF(Interrupt Flag):中断允许标志 IF=1表示接受外部中断
    • TF(Trap Flag):跟踪标志 TF=1表示单步运行 TF=0表示正常运行 

    总结:状态标志的值由指令执行后的结果决定,控制标志的值由特定指令设置或者清除。

    进位标志CF 和 溢出标志OF 的应用场合?

    进位标志只使用在无符号数运算内,溢出标志只使用在有符号数运算内。

     

    Lesson 4 

    Ⅰ.数据在内存储器中的存储情况

    • 字节:8位
    • 字:16位
    • 双字:32位

    Ⅱ.8086CPU

    • 20根地址线,最大可寻址空间为2^{20}=1MB,从00000H~FFFFFH
    • 16根数据线(因为该CPU的机器字长为16位)

    从逻辑地址转化到物理地址的公式:PA(Physical Address) = SA(Segment Address)×16+EA(Extra Address)

    物理地址=段地址×16+段内偏移 (16表示每段的大小为16位)

    1.为什么每段最大限制为64KB?

    因为该CPU里只有16根数据线,所以每次访问数据的时候,最多访问16位,也就是2^{16}=64KB

    2.为什么只能通过逻辑地址向物理地址转换?

    因为一个物理地址可以对映多个逻辑地址。

    解:设物理地址为P,段地址为S,段内偏移为E。

    若逻辑地址已知,即S,E均为已知数,则可以求出P。

    若物理地址已知,即P为已知数,此时只能得出一个一次函数:XXX = 16*S + E,逻辑地址不唯一。

    Ⅲ.补充内容

    最小模式和最大模式:

    • 最小模式:在系统中只有一个微处理器。
    • 最大模式:在系统中有两个或两个以上的微处理器(主处理器,协处理器)

    周期:

    • 指令周期:执行一条指令所需要的时间
    • 总线周期:CPU与外部交换一次信息(通过总线)
    • 时钟周期:时钟脉冲的重复周期

    特殊地,8086CPU的总线周期至少由4个时钟周期组成,分别以T1,T2,T3,T4表示,一个总线周期完成一次数据传输,在T1期间由CPU输出地址,在T2,T3,T4期间传输数据。

    Ⅳ.8086的引脚

    • 地址总线
    • 数据总线
    • 控制总线
    • 其他(时钟与电源)

    8086

    • AD_{15}~AD_{0}          地址/数据复用引脚
    • A_{19}/S_{6}~A_{16}/S_{3}   地址/状态总线复用
    • \overline{BHE}/S_{7}             高8位数据是否有效(低电频有效),=0时有效,=1时无效。用于在取数据时,确定所取数据的位数(8位、16位)。
    • \overline{RD}                      读信号(低电频有效),=0时表示正在读存储器/IO操作。
    • \overline{WR}                     写信号(低电频有效),=0时表示正在CPU正在对存储器或I/O端口进行写操作。
    • ALE                    地址锁存允许信号,在总线周期T1时钟周期时产生正脉冲,利用其下降沿将地址信息存入地址锁存器,目的是将地址信息保存起来,然后再传输数据信息,达到地址信息与数据信息分时复用传送目的。
    • M/\overline{IO}                  在最小方式工作(即在系统中只有一个微处理器)的情况下,=1表示CPU和存储器进行数据传输;=0表示CPU和I/O设备进行数据传输;在DMA方式下,M/IO为高阻态;

    1.为什么数据总线为双向,地址总线只输出?

    因为通过内存储器(或通过I/O设备)之间交换数据是双向的。而寻求某个内存单元的地址信号只能由CPU发出,所以为输出(单向)。

    2.三态

    高电频,低电频,高阻态(相当于连接为断开的情况,即等于没有连接在总线上,不影响其他器件的工作)

    MOV AL, 05H
    MOV AX, 3064H
    0100 B005
    0102 B86430
    0105 

    第一条指令翻译成B005,16位(0100-0101),其中MOV AL = B0,05H不变,

    第二条指令翻译成B86430,24位(0102-0104),其中MOV AL = B8,6430高高低低(30H为高位,所以放在0104;64H为低位,所以放在0103。)

    为什么不操作数不能同为内存储器数?

    个人猜测:主要因为CPU需要掌握控制权,如果两个内存储器数直接转移的话没有经过CPU,这是CPU无法容忍的。

    Ⅴ.QUICK QUIZ

    1.MOV AL, [2000H]是否正确?

    √,因为[2000H]表示寻找地址为2000H里所装的内容,也就是,向内存储器里寻找一个数,汇编此时根据AL的位数(8位),确定在内存储器里所需要取的数也为8位。

     

    Lesson 5 指令系统

    Ⅰ.寻址方式

      1.立即寻址        操作数包含在指令(代码)中

      2.寄存器寻址    操作数存放在CPU的某个寄存器中

      3.存储器寻址    操作数存放在存储器中

        存储器直接寻址(有效地址EA直接由指令给出)

        存储器间接寻址(有效地址由其他方式给出)

        基址寻址(基址寄存器+位移量) 

        变址寻址(变址寄存器+位移量)

        基址变址寻址(必须是一个基址寄存器和一个变址寄存器的组合)

    • 基址寄存器[BP(Base Pointer), BX(Base Register)]   变址寄存器[SI(Source Index), DI(Destination Index)],除此之外,CX, DX, CX都不允许出现在[ ]之中,即寄存器间接寻址不能[CX]...
    • 逻辑地址=段寄存器 : [基址寄存器+变址寄存器*比例因子+位移量]
    • 一遇到BP, 段寄存器为SS, 其余则为DS
    • 在[ ]之中用+和*,在[ ]之外不用 e.g. [BX+DI] ->[BX][DI]     [2*BX] -> 2[BX]

    4.I/O端口寻址   操作数存放在I/O接口电路的端口中

    Ⅱ.判断指令

    • 源操作数和目的操作数的字长一致
    • 源操作数和目的操作数不能同为内存单元(内存数)
    • 立即数不能作为目的操作数

    Ⅲ.数据传输指令

      1.MOV move

    • CS不能作为目的操作数
    • 源操作数和目的操作数不能同时为段寄存器
    • 立即数不能直接送给段寄存器

      2.XCHG exchange

    • 不允许使用立即数
    • 不允许使用段寄存器

      3.PUSH POP

    • 不允许使用立即数
    • 必须以字为单位(16位)
    • 源操作数和目的操作数可以是16位通用寄存器,存储器和段寄存器,但POP指令不能用CS

      4.XLAT translate

    •    XLAT ; AL<-DS : [BX+AL]  表示将数据段中首单元偏移量地址在BX,顺序号在AL的表的数据项单元内容取出送AL。
    MOV BX, 1000H
    MOV AL, 7
    XLAT

      5.LEA load address

    • 只能将取出的有效地址存在16位的通用寄存器中(段寄存器)
    • 需要取出有效地址的数只能是存储器数

      6.LDS/LES load DS/ load ES

    • LDS  reg16mem; 将mem指定的存储器双字中存放的逻辑地址(指针)送16位通用寄存器reg16和DS 
    • LES  reg16mem; 将mem指定的存储器双字中存放的逻辑地址(指针)送16位通用寄存器reg16和ES 

      7.LAHF/SAHF  load AH status flags / set AH status flags

    • LAHF 是将标志寄存器F的低8位传送到寄存器AH中
    • SAHF 是将寄存器AH内容传送到标志寄存器F的低8位中
    • LAHF不影响标志位,SAHF影响标志位

      8.PUSHF/POPF

    • PUSHF是将标志寄存器F压入堆栈
    • POPF是将堆栈栈顶内容弹出至标志寄存器F
    • PUSHF不影响标志位,POPF影响标志位

      9.IN/OUT input from port / output from port

    • 指令中存放数据的寄存器只能用累加器,8位数据用AL,16位数据用AX
    • 对于地址,8位的端口地址可以直接写在指令中,即直接寻址;但16位的端口地址不能直接写在指令中,必须放在寄存器DX中,指令中只给出DX,即寄存器间接寻址。

    Ⅳ.算术运算指令

    d, s不能为段寄存器

    一、加法

      1.ADD d, s 不带进位的加法

    • 使用情况,一次8位运算就可以结束。
    • CF=1表示和的最高位向前有进位;AF=1表示和的D3位向D4位有进位;OF=1表示当两个操作数的符号相同,而结果符号与之相反

      2.ADC d, s  带进位加  add by carry

    • 使用情况:多次运算,分步

      3.INC d  自加1  increase

    • INC不影响CF标志(就算有进位也不改变CF)

    二、减法

      1.SUB d, s 不带进位的减法

    • CF=1表示和的最高位向前有借位;AF=1表示和的D3位向D4位有借位;OF=1表示当两个操作数的符号相同,而结果符号与之相反

      2.SBB d, s 带进位的减法

      3.DEC d 自减1

    • DEC不影响CF标志

     4.NEG d 取负指令 negative

    • 将目的数取负后送回给d, (d) \leftarrow (\overline{d})+1
    • NEG是取负,不是取反,影响标志位

      5.CMP 比较 compare

    • 仅将目的数d与操作数s相减,结果并不送回d中
    • CMP影响标志位,但不影响操作数

    三、乘法

      1.MUL s 无符号数乘法 multiply

    • 当s为字节数(8)的时候,AX  \leftarrow AL × s
    • 当s为字数据(16)的时候,DX:AX \leftarrow AX × s

      2.IMUL s 有符号数乘法

    • 当s为字节数(8)的时候,AX  \leftarrow AL × s
    • 当s为字数据(16)的时候,DX:AX \leftarrow AX × s

    四、除法

      1.DIV s 无符号数除法 division && 

      2.IDIV s有符号数除法

    • 当s为字节数(8)的时候,被除数在AX中
    • 当s为子数据(16)的时候,被除数在DX : AX中
    • AL/AX 为隐含的商寄存器
    • AH/DX为隐含的余数寄存器

    五、符号扩展

      1.CBW 字节符号扩展指令 change byte to word

    • AL_{7}=0,则AH = 0000 0000b = 00H
    • AL_{7}=1,则AH = 1111 1111b = FFH

     2.CWD 字节符号扩展指令 change word to double word

    • AX_{15}=0,则DX = 0000 0000 0000 0000b = 0000H
    • AX_{15}=1,则DX = 1111 1111 1111 1111b = FFFFH

    六、BCD码调整

      1.DAA 加法的压缩BCD码调整

    • 若AL低4位>9或AF=1,AL = AL + 06H
    • 若AL高4位>9或CF=1,AL = AL + 60H

    为什么在进行加法的时候需要对BCD码进行调整?

    举个栗子:

    1.

    14+16 = 0001 0010B + 0001 0110B = 2AH = 2?

    14+16 = 30

    2AH+06H = 30H //低4位>9

    2.

    68+89 = 0110 1000B + 1000 1001B = 1111 0001B =  F1H = ?1

    68+89 = 157

    F1H = (F0H+60H) + (01H+06H) = (1)57  //高4位>9 && 低4位AF=1

    Ⅴ.逻辑位移指令

    一、逻辑运算指令

      除逻辑“非”指令不影响标志外,其他逻辑运算指令均影响标志SF、ZF和PF,而OF和CF一定被置0,AF不确定。

      1. AND 逻辑与

    • 与0与某位清零
    • 与1与某位不变

      2. OR 逻辑或

    • 与0或某位不变
    • 与1或某位置一

      3. XOR 逻辑异或

    • 相同为0,不同为1
    • 两个相同的数异或 结果为0
    • 与0异或为其本身,与1异或为其相反数(0xor0 = 0 、1xor0 = 1 | 0xor1 = 1、1xor1 = 0)

      4. NOT 逻辑非

    • 取反

      5. TEST 测试指令

    • 将目的操作数与源操作数按位相“与”,只影响标志位不回送结果,常用于测试某些位是0或1

    为什么可以用来测试某些位是0还是1?

    举个栗子:

    TEST AL,80H; 测试最高位是0还是1?

    相当于AL每位与1000 0000B相与,影响标志位后,若ZF = 0,则最高位为0;若ZF = 1,则最高位为1;

    二、移位运算指令

    • 对8位或16位的通用寄存器或存储器进行移位,移位次数可以是1-255;当移位次数为1的时候,可直接写在指令中;当移位次数>1的时候,必须先放在寄存器CL中;
    • 影响标志OF、SF、ZF、PF、CF,但AF不确定
    • 当移位次数为1时,若移位结果使最高位符号位发生变化,则溢出标志OF=1,否则OF=0;当移位次数超过1时,OF无效

      1. SHL 逻辑左移

    • SHL d, count(1, CL);
    • 将目的操作数d向左移动count位,右边补0,最左边移入CF

    如何利用SHL指令使BX的值乘3?

    MOV AX BX;

    SHL BX 1;

    ADD BX, AX;

      2. SHR 逻辑右移

    • SHR d, count(1, CL);
    • 将操作数内容右移count位,左边补0,最右边移入CF

      3. SAL 算术左移

    • 与逻辑左移完全相同

      4. SAR 算术右移

    • SAR d, count(1, CL);
    • 将操作数内容右移count位,符号位不变,最右边移入CF

      循环移位:

      5. ROL 向左小循环

    • ROL d, count(1, CL);
    • 将操作数d内容左移,最高位循环移入最低位,同时移入CF

      6. ROR 向右小循环

    • ROR d, count(1, CL);
    • 将操作数d的内容右移,最低位循环移入最高位,同时移入CF

      7. RCL 带进位循环左移指令

    • RCL d, count(1, CL);
    • 将操作数d的内容左移,最高位循环移入CF,而CF循环移入最低位

      8. RCR 带进位循环右移指令

    • RCR d, count(1, CL);
    • 将操作数d的内容右移,最低位循环移入CF,而CF循环移入最高位

    Q:5种一条指令置DX为0方法

    A: (1) MOV DX,0000H;(2) LEA DX,[0000H];(3) SUB DX,DX;(4) AND DX,0000H;(5) XOR DX,DX;

    Ⅵ.控制转移指令

    CS:IP总是指向下一条即将执行的指令的地址,通过改变IP和CS的值,可以改变程序的执行顺序

    100

    一、无条件转移

      1. JMP 目标地址

    • 段内直接转移(短转移):相对转移、位移量在指令中占一个字节,转移范围不超过(-128) ~ (+127)
    • 段内直接转移(近转移):相对转移、位移量在指令中占两个字节,转移范围是段内(-32768)~(+32767)
    • 段内间接转移(寄存器间接):绝对转移、目标地址在16位的通用寄存器中,转移范围是段内任何地方(0~65535)
    • 段内间接转移(存储器间接):绝对转移、目标地址在存储器中占两个字节,转移范围是段内任何地方(0~65535)
    • 段内直接转移(远转移):绝对转移、目标地址在指令中占4个字节(2字节IP,2字节CS),转移范围为存储器的任何地方
    • 段间间接转移(存储器间接):绝对转移、目标地址在存储器中占4个字节(2字节IP,2字节CS),转移范围为存储器的任何地方

      2. CALL 子程序(过程)地址

    • 子程序(过程)调用

      3. RET 或 RET n 

    • 从子程序(过程)返回

    二、条件转移

    怎么记忆条件转移指令?

    无符号数:

    A:Above;    B:Below;    C:Carry;   

    其他:

    E:Eequl;    N:Not;    Z:Zero;    PE:Parity Even;    PO:Parity Odd;

    有符号数:

    G:Greater;    L:Less;    S:Sign;    O:Overflow;

    举个栗子:

    JZ/JE:表示结果为0,Z表示ZF=1,E表示Equal;

    JNZ/JNE:表示结果不为0,JNZ表示ZF not 1,JNE表示Not equal.

    • 若满足条件,则程序转移到标号地址去执行,否则继续执行下一条指令
    • 条件转移都是短转移,范围为(-128) ~ (+127)
    • 简单转移:条件使由寄存器中的标志位的状态决定的转移;  复制转移:条件是由有符号数和无符号数的大小决定的转移

    三、循环控制

    • 循环控制指令用来控制程序段循环执行的次数,循环次数必须放在CX寄存器中
    • 循环控制指令使段内短距离相对转移指令,转移距离为(-128) ~ (+127)

    写个练习题:将下列C语言代码转换为汇编指令

    a1, a2为无符号数
    if(a1 > b1)
        a1 = a1*2;
    else if(a1 < b1)
        a1高两位;
    else
        a1按位取反;
    
        MOV AL, a1;
        MOV BL, b1;
        CMP a1, b1;
        JB A1;     
        JE A2;
        SHL AL, 1;
        JMP A3;
    A1: OR AL, 0C0H,
        JMP A3;
    A2: NOT AL;    
    A3: ...

      1. while循环

    AX=0; CX=100;
    while(CX >= 1)
    {
        AX = AX + CX;
        CX--;
    }
    ...
         MOV AX, 0;
         MOV CX, 100;
    A1:  CMP CX, 1;
         JB A2;
         ADD AX, CX;
         DEC CX;
         JMP A1;
    A2   ...

      2. do while循环

    AX = 0;
    CX = 100;
    do
    {
        AX = AX + CX;
        CX--;
    }while(CX >=1);
         MOV AX, 0;
         MOV CX 100;
    A1:  ADD AX CX;
         DEC CX;
         CMP AX, 1;
         JAE A1;
         ...

     

    Lesson 6 汇编语言程序设计

    Ⅰ.完整段结构

    STACK SEGMENT
        ;定义堆栈
        DW 256 DUP(?)
    STACK ENDS
    
    DATA SEGMENT
        AA DB 12, 25, 36
    DATA ENDS
    
    CODE SEGMENT
        ASSUME CS:CODE, DS:DATA, SS:STACK;
        START: ...
               ...
               ...
        
    CODE ENDS
        END START

    Ⅱ.常量、标识符、标号和表达式

    一、常量

      1.数字常量:直接用数字表示的常量

    • 二进制 Binary
    • 十进制 Decimal
    • 十六进制 Hexadecimal (字母打头必须前面补0,否则将出现汇编语法错误)

      2.字符串常量:包含在单引号内的一个或两个ASCII字符,它所代表的数值就是该字符的ASCII码

    • ‘0’ : 30H
    • ‘A’ : 41H
    • 'a' : 61H

      3.符号常量:用标识符(常量名)表示的常量,它具有一个设定的数值从而被引用

    二、标识符

      有特定意义的字符序列,标识符可用作符号常量、名字、变量和标号等

    • 命名规则
    1. 0 ≤ 31个ASCII码字符
    2. 由[ A-Z ]、[ a-z ]、[ 0-9 ] 、[ ? ]、[ @ ]、[ $ ] 及 [ _ ] 构成,其中除数字以外,所有规定的字符都可作为标识符的第一个字符
    3. ? 不能单独作为标识符
    4. 无独立的保留字及运算符

    三、标号

      指令性语句存放地址的符号表示,常用语指令的转移和子程序的调用

    四、表达式与运算符

      由操作数(常量、变量、标号)和运算符构成

    1.逻辑运算符:AND、OR、NOT、XOR

    AND AL, 86H AND 0FH ;其中第一个AND是指令、第二个AND是逻辑运算符
    • 逻辑运算符只能对常数(或相当等于常数)进行运算
    • CPU不执行任何操作,在汇编之后,在目标程序中只是一个常数

    2.运算符:EQ(equal)、NE(not equal)、LT(less than)、LE(less equal)、GT(greater than)、GE(greater equal)

    Ⅲ. 指示性语句

    一、程序结束伪指令END

    格式:END 标号 ; 标号为程序中第一条指令性语句标号

    二、段定义伪指令

    1.段定义伪指令

    段名  SEGMENT  [定位方式][组合方式][‘类别名’]
    	…
    段名  ENDS
    
    •   定义数据段、附加段和堆栈段时,处于SEGMENT/ENDS伪指令中间的语句,只能包括伪指令语句,不能包括指令语句。

    2.段寄存器说明伪指令

    ASSUME 段寄存器:段名1, 段寄存器:段名2...
    
    • 在代码段告诉汇编程序CS、DS、ES、SS应具有的符号段基址,但是段寄存器(CS除外)还必须用传送指令赋值
    MOV AX, DATA
    MOV DS, AX
    ; 为什么不能直接MOV DS DATA?
    ; 因为这里的DATA是立即数,立即数不能直接送给段寄存器

    三、数据定义伪指令

    • 指令
    DB(Define byte) (8位)一个字节
    DW(Define word) (16位)两个字节
    DD(Define double word) (32位)四个字节
    • 参数
    DB  10       DUP(12H)
    ;   复制次数  DUP(填充内容)

    四、符号定义伪指令

    • EQU:符号常量 EQU 表达式;
    • PURGE: PURGE 名字;

      (在赋予新值前需要使用PURGE撤销)

    • “=”:符号常量 = 表达式

      (其功能与EQU相似,只是无须使用PURGE命令而已)

    五、名字和变量

    1.名字

    • 在源程序的段定义语句中命名取定,段名可以作为段基址使用
    ARRAY  DB  10H,5AH,0C7H,98H,’ABCD’
    COUNT EQU $-ARRAY; 返回ARRAY长度,其中$表示该行的偏移地址

    2.变量

    • 求段基址:MOV AX,SEG AA;(其中SEG AA为立即寻址,是AA的段地址)
    • 求偏移地址:MOV AX,OFFSET BB;(其中OFFSET BB为立即寻址,是BB的偏移地址)
    • 求符号名的类型值:MOV AL,TYPE CC;(其中TYPE CC为立即寻址,是CC类型的字节数)
    • 求长度属性:BUF DW N DUP(?);LENGTH BUF = N ;说明:只有当数据用赋值符DUP定义时,LENGTH才等于数组的元素个数,否则LENGTH等于1
    • 规模属性:SIZE 符号名;返回变量的总字节数:SIZE=LENGTH*TYPE

    3.属性运算符

    • 类型指定运算符PTR:INC BYTE PTR [2000H];按PTR前面指定的类型去寻址

    Ⅳ.DOS系统功能调用

    1. 传送入口参数到指定寄存器
    2. 调用子功能的功能编号放在AH寄存器中
    3. 执行 INT 21H指令

      调用结束后返回相应结果,并由CF标志表示调用的是否成功,当出现调用错误时CF=1AX返回出错编号

    1.键盘单字符输入(1号)

    MOV AH, 1
    INT 21H
    • 功能:等待从键盘输入一个字符
    • 返回:AL = (输入的ASCII码的值)

    2.输出单字符(2号)

    MOV DL, 'A'
    MOV AH, 02
    INT 21H
    • 功能:将DL里的字符从屏幕上输出

    3.输出字符串(9号)

    MOV DX, OFFSET BUF
    MOV AH, 09
    INT 21H
    • 功能:BUF中以 '$' 为结束标志的字符串显示在屏幕上,当无 '$' 时会出现乱码。解决方案:初始化数组时DUP('$')

    4.键盘输入字符串(10号)

    MOV DX, OFFSET BUF; DS: DX为键盘缓冲区
    MOV AH, OAH
    INT 21H
    • 功能:等待从键盘输入一串字符,回车结束,字符串存入键盘缓冲区
    • 键盘缓冲区定义:
    BUF DB 81        ; 缓冲区的大小
        DB ?         ; 实际输入的字符大小
        DB 80 DUP(?) ; 字符串存放区

    5.返回操作系统(4CH)

    MOV AH, 4CH
    INT 21H
    • 功能:将控制权交给操作系统

    本章习题:

    1.试编制一程序,求出下列公式中的Z值,并存放在RESULT单元中。其中,XY的值分别存放在VARXVARY单元中。

    Z=[(X+Y)×8-X]/2

    DATAS SEGMENT
        ;此处输入数据段代码  
        VARX DB 4
        VARY DB 4
        RESULT DB ?
    DATAS ENDS
    
    STACKS SEGMENT
        ;此处输入堆栈段代码
    STACKS ENDS
    
    CODES SEGMENT
        ASSUME CS:CODES,DS:DATAS,SS:STACKS
    START:
        MOV AX,DATAS
        MOV DS,AX
        ;此处输入代码段代码
        MOV AL, VARX
        ADD AL, VARY 
        MOV CL, 3    ; 移位>1需要先放入CL
        SHL AL, CL    
        SUB AL, VARX 
        SAR AL, 1
        MOV RESULT, AL
        MOV AH, 4CH
        INT 21H
    CODES ENDS
        END START
    

    2.内存中自TABLESQ开始的10个单元连续存放着自然数09的平方值,任给一数x(0 <= x <= 9)在XX单元中,查表求出X的平方值,将结果存入YY单元中(利用DOS的1号功能调用)。

    DATAS SEGMENT
        ;此处输入数据段代码  
    	TABLESQ DB 0, 1, 4, 9, 16, 25, 36, 49, 64, 81
    	XX DB ?
    	YY DB ?
    DATAS ENDS
    
    STACKS SEGMENT
        ;此处输入堆栈段代码
    STACKS ENDS
    
    CODES SEGMENT
        ASSUME CS:CODES,DS:DATAS,SS:STACKS
    START:
        MOV AX,DATAS
        MOV DS,AX
        ;此处输入代码段代码
    	MOV AH, 1 ;输入一个数
    	INT 21H
    	SUB AL, 30H ;ASCII->数字
    	MOV XX, AL
    	
    	MOV BX, OFFSET TABLESQ ;取值
    	XLAT
    	MOV YY, AL
    	
        MOV AH, 4CH
        INT 21H
        
    CODES ENDS
        END START
    

    3.从键盘输入字符 "HELLO SUGAR"并显示在屏上

    DATAS SEGMENT
        ;此处输入数据段代码  
        KEYBUF DB 12, ?, 13 DUP('$')
    DATAS ENDS
    
    STACKS SEGMENT
        ;此处输入堆栈段代码
    STACKS ENDS
    
    CODES SEGMENT
        ASSUME CS:CODES,DS:DATAS,SS:STACKS
    START:
        MOV AX,DATAS
        MOV DS,AX
        ;此处输入代码段代码
        MOV DX, OFFSET KEYBUF
        ;KEYBUF[0]是首地址,KEYBUF[1]是个数
        MOV AH, 0AH
        INT 21H
        MOV AH, 09H
        INT 21H
        MOV AH,4CH
        INT 21H
    CODES ENDS
        END START

     

    8255和8253

    开始之前首先认真的忏悔一下 不知道为啥自己上课整理的内容 到这之前就停了。可能因为自己去忙别的事情了吧,awsl。每年都是:下个学期会不那么忙,后来发现都是骗人的。

    总之这个就是考试之前有一些东西需要总结。

    Ⅰ.8253

    1. 8253控制字最后一位D0=0表示二进制,D1表示十进制,how does it supposed to understand?

    老师上课的时候说有很多人搞不懂这个,然后我上课的那一瞬间是懂了,然后现在再看自己记的笔记就完全...忘记了。

    8253的工作方式控制字D0=1时,表示写入计数值为BCD码,但写入时,按十六进制数写入。

    展开全文
  • 期末考快到了,有些学生因为没有理解数学概念,复习上会遇到困难。...家长不妨让孩子记住,符号方向就是鳄鱼嘴巴一样,当然越大越好吃!2、巧背九乘法口诀九乘法口诀经常记不住?其实只要在...

    b980aa8c113d6e315687272f20a96a18.png

    期末考快到了,有些学生因为没有理解数学概念,复习上会遇到困难。所以今天,小编特意为家长们介绍八个神奇的数学小技巧( ⊙ o ⊙ )!希望孩子们在考试的时候能派上用场吧。


    1、比大小的绝招:鳄鱼记忆法

    有些低年级的小学生在比数字大小时,容易用错“<”和“>”这两个比较符号。

    家长不妨让孩子记住,符号方向就像是鳄鱼嘴巴一样,当然越大的越好吃!

    46a3b173f4be0878e3f81f415ee208bf.png

    2、巧背九的乘法口诀

    九的乘法口诀经常记不住?其实只要在十位数上从0写到9,个位数上从9到数回0,马上写出完整的表格。考试更轻松!

    6f6eedc286e2851a85e1f7dddc8940a4.png

    3、90以上的两位数相乘

    两位数的乘法很容易让孩子漏算数字,特别是90以上的互乘就更难了。其实有这样的简单技巧,比如97x96=9312来说,只要拿100减乘数与被乘数,把答案分别相乘与相加,把乘出来的答案摆在后面,用100减加出来的总和后摆在前面,答案竟然神奇得和传统算法一模一样。试试吧!

    2e09e8353f4a5c2a18d7f1ac674e8b74.png

    4、两位数与11相乘

    任何二位数和11相乘,只要把十位数和个位数拆开,中间再插入十位数和个位数的总和,就不用麻烦地乘来乘去啦。

    举个例子:38 × 11 ,3做百位,8做个位,十位数3+8=11,所以进一位,就变成是418了。

    8824b68176a66c331f69b9a59dcc5518.png

    5、分数加减绝招:蝴蝶计算法

    以往学生会找出两分母的最小公倍数再计算。但其实只要在算式上画只蝴蝶就解决了。把蝴蝶翅膀圈在一起的部分相乘写在触角里面,彼此相加就是答案的分子,再把分母彼此相乘,就是答案的分母。减法也是一样的方式,只要把触角里的数字改成相减即可。

    a4d9a22f81613b3bc9f532b103842e89.png

    6、分数乘整数:连线计算法

    如图:把分母和整数间连一条线,算出24是4的6倍,然后再把线连到分子3,用6乘以3,答案18就这么轻松算出来。

    4bc632cb8cc44373dda1fd9107baa0b1.png

    7、百分比计算技巧

    计算百分比的时候,其实“%”就能抵消两个零。比如计算“300的12%”时,只需要把“300”后面的两个“0”去掉,就可以划去“%”了,剩下就是“3x12=36”了,是不是很轻松。

    如果两个数都有出现个位数是“0”的情况下,就用另一种方式:

    916bcf8e38b9296ba019d4867b4e86aa.png

    8、十几乘以十几的口诀

    口诀:头乘头,尾加尾,尾乘尾

    例:12×14=?

    口诀算法:1×1=1 2+4=6 2×4=8

    答案:12×14=168

    注:个位相乘,不够两位数要用0占位。个位相乘后是两位数,记得加在前一位!

    比如13x16=?

    口诀算法:1x1=1 3+6=9 3x6=18

    此时的18的十位数“1”就要和“9”加在一起,等于“10”后,又往百位数前进一步,让百位数的1变成2,这样13x16=208.

    2001c1035d82e6b14606ce47984ecaf4.png

    好了,小编就分享到这里。家长们不要忘记,让学生们上远大小状元多做数学练习哦!我们下期再见吧~祝孩子们考试顺利,成绩可喜。加油!


    本文作者:元老师;欢迎关注公众号:远大家长通,阅读更多精彩好文章!

    展开全文
  • Java自学-I/O 中文问题

    2019-05-12 14:45:28
    一个棋盘一样,不同字,处于不同位置,而不同位置,有不同数字编号。 有棋盘很小,只能放数字和英文 有大一点,还能放中文 有“足够”大,能够放下世界人民所使用所有文字和符号 如图所示,...

    Java中的编码中文问题

    步骤 1 : 编码概念

    计算机存放数据只能存放数字,所有的字符都会被转换为不同的数字。
    就像一个棋盘一样,不同的字,处于不同的位置,而不同的位置,有不同的数字编号。
    有的棋盘很小,只能放数字和英文
    有的大一点,还能放中文
    有的“足够”大,能够放下世界人民所使用的所有文字和符号

    如图所示,英文字符 A 能够放在所有的棋盘里,而且位置都差不多
    中文字符, 中文字符 能够放在后两种棋盘里,并且位置不一样,而且在小的那个棋盘里,就放不下中文
    编码概念
    步骤 2 : 常见编码

    工作后经常接触的编码方式有如下几种:
    ISO-8859-1 ASCII 数字和西欧字母
    GBK GB2312 BIG5 中文
    UNICODE (统一码,万国码)

    其中
    ISO-8859-1 包含 ASCII
    GB2312 是简体中文,BIG5是繁体中文,GBK同时包含简体和繁体以及日文。
    UNICODE 包括了所有的文字,无论中文,英文,藏文,法文,世界所有的文字都包含其中

    步骤 3 : UNICODE和UTF

    根据前面的学习,我们了解到不同的编码方式对应不同的棋盘,而UNICODE因为要存放所有的数据,那么它的棋盘是最大的。
    不仅如此,棋盘里每个数字都是很长的(4个字节),因为不仅要表示字母,还要表示汉字等。

    如果完全按照UNICODE的方式来存储数据,就会有很大的浪费。
    比如在ISO-8859-1中,a 字符对应的数字是0x61
    而UNICODE中对应的数字是 0x00000061,倘若一篇文章大部分都是英文字母,那么按照UNICODE的方式进行数据保存就会消耗很多空间

    在这种情况下,就出现了UNICODE的各种减肥子编码, 比如UTF-8对数字和字母就使用一个字节,而对汉字就使用3个字节,从而达到了减肥还能保证健康的效果

    UTF-8,UTF-16和UTF-32 针对不同类型的数据有不同的减肥效果,一般说来UTF-8是比较常用的方式
    UNICODE和UTF
    步骤 4 : Java采用的是Unicode

    写在.java源代码中的汉字,在执行之后,都会变成JVM中的字符。
    而这些中文字符采用的编码方式,都是使用UNICODE. "中"字对应的UNICODE是4E2D,所以在内存中,实际保存的数据就是十六进制的0x4E2D, 也就是十进制的20013。

    package stream;
     
    public class TestStream {
        public static void main(String[] args) {
            String str = "中";
        }
    }
    

    步骤 5 : 一个汉字使用不同编码方式的表现

    以字符 为例,查看其在不同编码方式下的值是多少

    也即在不同的棋盘上的位置
    一个汉字使用不同编码方式的表现

    package stream;
     
    import java.io.UnsupportedEncodingException;
     
    public class TestStream {
     
        public static void main(String[] args) {
            String str = "中";
            showCode(str);
        }
     
        private static void showCode(String str) {
            String[] encodes = { "BIG5", "GBK", "GB2312", "UTF-8", "UTF-16", "UTF-32" };
            for (String encode : encodes) {
                showCode(str, encode);
            }
     
        }
     
        private static void showCode(String str, String encode) {
            try {
                System.out.printf("字符: \"%s\" 的在编码方式%s下的十六进制值是%n", str, encode);
                byte[] bs = str.getBytes(encode);
     
                for (byte b : bs) {
                    int i = b&0xff;
                    System.out.print(Integer.toHexString(i) + "\t");
                }
                System.out.println();
                System.out.println();
            } catch (UnsupportedEncodingException e) {
                System.out.printf("UnsupportedEncodingException: %s编码方式无法解析字符%s\n", encode, str);
            }
        }
    }
    

    步骤 6 : 文件的编码方式-记事本

    字符在文件中的保存肯定也是以数字形式保存的,即对应在不同的棋盘上的不同的数字
    记事本打开任意文本文件,并且另存为,就能够在编码这里看到一个下拉。
    ANSI 这个不是ASCII的意思,而是采用本地编码的意思。如果你是中文的操作系统,就会使GBK,如果是英文的就会是ISO-8859-1
    Unicode UNICODE原生的编码方式
    Unicode big endian 另一个 UNICODE编码方式
    UTF-8 最常见的UTF-8编码方式,数字和字母用一个字节, 汉字用3个字节。
    文件的编码方式-记事本
    步骤 7 : 文件的编码方式-eclipse

    eclipse也有类似的编码方式,右键任意文本文件,点击最下面的"property"
    就可以看到Text file encoding
    也有ISO-8859-1,GBK,UTF-8等等选项。
    其他的US-ASCII,UTF-16,UTF-16BE,UTF-16LE不常用。
    文件的编码方式-eclipse
    步骤 8 : 用FileInputStream 字节流正确读取中文

    为了能够正确的读取中文内容

    1. 必须了解文本是以哪种编码方式保存字符的
    2. 使用字节流读取了文本后,再使用对应的编码方式去识别这些数字,得到正确的字符
      如本例,一个文件中的内容是字符,编码方式是GBK,那么读出来的数据一定是D6D0。
      再使用GBK编码方式识别D6D0,就能正确的得到字符

    注: 在GBK的棋盘上找到的字后,JVM会自动找到在UNICODE这个棋盘上对应的数字,并且以UNICODE上的数字保存在内存中。
    用FileInputStream 字节流正确读取中文

    package stream;
       
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
       
    public class TestStream {
       
        public static void main(String[] args) {
            File f = new File("E:\\project\\j2se\\src\\test.txt");
            try (FileInputStream fis = new FileInputStream(f);) {
                byte[] all = new byte[(int) f.length()];
                fis.read(all);
       
                //文件中读出来的数据是
                System.out.println("文件中读出来的数据是:");
                for (byte b : all)
                {
                    int i = b&0x000000ff;  //只取16进制的后两位
                    System.out.println(Integer.toHexString(i));
                }
                System.out.println("把这个数字,放在GBK的棋盘上去:");
                String str = new String(all,"GBK");
                System.out.println(str);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
       
        }
    }
    

    步骤 9 : 用FileReader 字符流正确读取中文

    FileReader得到的是字符,所以一定是已经把字节根据某种编码识别成了字符
    而FileReader使用的编码方式是Charset.defaultCharset()的返回值,如果是中文的操作系统,就是GBK
    FileReader是不能手动设置编码方式的,为了使用其他的编码方式,只能使用InputStreamReader来代替,像这样:

    new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8"));
    

    在本例中,用记事本另存为UTF-8格式,然后用UTF-8就能识别对应的中文了。

    解释: 为什么中字前面有一个?
    如果是使用记事本另存为UTF-8的格式,那么在第一个字节有一个标示符,叫做BOM用来标志这个文件是用UTF-8来编码的。
    用FileReader 字符流正确读取中文

    package stream;
     
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.UnsupportedEncodingException;
    import java.nio.charset.Charset;
     
    public class TestStream {
     
        public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException {
            File f = new File("E:\\project\\j2se\\src\\test.txt");
            System.out.println("默认编码方式:"+Charset.defaultCharset());
            //FileReader得到的是字符,所以一定是已经把字节根据某种编码识别成了字符了
            //而FileReader使用的编码方式是Charset.defaultCharset()的返回值,如果是中文的操作系统,就是GBK
            try (FileReader fr = new FileReader(f)) {
                char[] cs = new char[(int) f.length()];
                fr.read(cs);
                System.out.printf("FileReader会使用默认的编码方式%s,识别出来的字符是:%n",Charset.defaultCharset());
                System.out.println(new String(cs));
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //FileReader是不能手动设置编码方式的,为了使用其他的编码方式,只能使用InputStreamReader来代替
            //并且使用new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8")); 这样的形式
            try (InputStreamReader isr = new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8"))) {
                char[] cs = new char[(int) f.length()];
                isr.read(cs);
                System.out.printf("InputStreamReader 指定编码方式UTF-8,识别出来的字符是:%n");
                System.out.println(new String(cs));
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
             
        }
    }
    

    练习移除BOM

    如果用记事本根据UTF-8编码保存汉字就会在最前面生成一段标示符,这个标示符用于表示该文件是使用UTF-8编码的。

    找出这段标示符对应的十六进制,并且开发一个方法,自动去除这段标示符

    答案 :

    package stream;
       
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.Arrays;
       
    public class TestStream {
       
        public static void main(String[] args) {
            File f = new File("E:\\project\\j2se\\src\\test.txt");
            try (FileInputStream fis = new FileInputStream(f);) {
                byte[] all = new byte[(int) f.length()];
                fis.read(all);
                System.out.println("首先确认按照UTF-8识别出来有?");
                String str = new String(all,"UTF-8");
                System.out.println(str);
                System.out.println("根据前面的所学,知道'中'字对应的UTF-8编码是:e4 b8 ad");
                System.out.println("打印出文件里所有的数据的16进制是:");
                for (byte b : all) {
                    int i = b&0xff;
                    System.out.print(Integer.toHexString(i)+ " ");
                }
                System.out.println();
                System.out.println("通过观察法得出 UTF-8的 BOM 是 ef bb bf");
                byte[] bom = new byte[3];
                bom[0] = (byte) 0xef;
                bom[1] = (byte) 0xbb;
                bom[2] = (byte) 0xbf;
                byte[] fileContentWithoutBOM= removeBom(all,bom);
                System.out.println("去掉了BOM之后的数据的16进制是:");
                for (byte b : fileContentWithoutBOM) {
                    int i = b&0xff;
                    System.out.print(Integer.toHexString(i)+ " ");
                }           
                System.out.println();
                System.out.println("对应的字符串就没有问号了:");
                String strWithoutBOM=new String(fileContentWithoutBOM,"UTF-8");
                System.out.println(strWithoutBOM);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
       
        }
     
        private static byte[] removeBom(byte[] all, byte[] bom) {
            return Arrays.copyOfRange(all, bom.length, all.length);
        }
    }
    
    展开全文
  • 一个棋盘一样,不同字,处于不同位置,而不同位置,有不同数字编号。 有棋盘很小,只能放数字和英文 有大一点,还能放中文 有“足够”大,能够放下世界人民所使用所有文字和符号如图所示,英文...

    Java中的编码中文问题

    步骤 1 : 编码概念

    计算机存放数据只能存放数字,所有的字符都会被转换为不同的数字。

    就像一个棋盘一样,不同的字,处于不同的位置,而不同的位置,有不同的数字编号。

    有的棋盘很小,只能放数字和英文 有的大一点,还能放中文 有的“足够”大,能够放下世界人民所使用的所有文字和符号

    如图所示,英文字符 A 能够放在所有的棋盘里,而且位置都差不多

    中文字符, 中文字符 能够放在后两种棋盘里,并且位置不一样,而且在小的那个棋盘里,就放不下中文

    2f8249f1db5bef73c9ceca81cb2a6463.png

    步骤 2 : 常见编码

    工作后经常接触的编码方式有如下几种:

    ISO-8859-1 ASCII 数字和西欧字母

    GBK GB2312 BIG5 中文

    UNICODE (统一码,万国码)

    其中 ISO-8859-1 包含 ASCII

    GB2312 是简体中文,BIG5是繁体中文,GBK同时包含简体和繁体以及日文。

    UNICODE 包括了所有的文字,无论中文,英文,藏文,法文,世界所有的文字都包含其中

    步骤 3 : UNICODE和UTF

    根据前面的学习,我们了解到不同的编码方式对应不同的棋盘,而UNICODE因为要存放所有的数据,那么它的棋盘是最大的。

    不仅如此,棋盘里每个数字都是很长的(4个字节),因为不仅要表示字母,还要表示汉字等。

    如果完全按照UNICODE的方式来存储数据,就会有很大的浪费。 比如在ISO-8859-1中,a 字符对应的数字是0x61 而UNICODE中对应的数字是 0x00000061,倘若一篇文章大部分都是英文字母,那么按照UNICODE的方式进行数据保存就会消耗很多空间

    在这种情况下,就出现了UNICODE的各种减肥子编码, 比如UTF-8对数字和字母就使用一个字节,而对汉字就使用3个字节,从而达到了减肥还能保证健康的效果

    UTF-8,UTF-16和UTF-32 针对不同类型的数据有不同的减肥效果,一般说来UTF-8是比较常用的方式

    cc8db19dccb13f242f0e683552c2fd2e.png

    步骤 4 : Java采用的是Unicode

    写在.java源代码中的汉字,在执行之后,都会变成JVM中的字符。 而这些中文字符采用的编码方式,都是使用UNICODE. "中"字对应的UNICODE是4E2D,所以在内存中,实际保存的数据就是十六进制的0x4E2D, 也就是十进制的20013。

    package 

    步骤 5 : 一个汉字使用不同编码方式的表现

    以字符 为例,查看其在不同编码方式下的值是多少

    也即在不同的棋盘上的位置

    4339be0151d7e91b3801a64f8ebd0e34.png
    package 

    步骤 6 : 文件的编码方式-记事本

    字符在文件中的保存肯定也是以数字形式保存的,即对应在不同的棋盘上的不同的数字

    记事本打开任意文本文件,并且另存为,就能够在编码这里看到一个下拉。

    ANSI 这个不是ASCII的意思,而是采用本地编码的意思。

    如果你是中文的操作系统,就会使GBK,如果是英文的就会是ISO-8859-1

    Unicode UNICODE原生的编码方式

    Unicode big endian 另一个 UNICODE编码方式

    UTF-8 最常见的UTF-8编码方式,数字和字母用一个字节, 汉字用3个字节。

    9e68542d5225bcaa5e1569d99e43f9bc.png

    步骤 7 : 文件的编码方式-eclipse

    eclipse也有类似的编码方式,右键任意文本文件,点击最下面的"property" 就可以看到Text file encoding 也有ISO-8859-1,GBK,UTF-8等等选项。 其他的US-ASCII,UTF-16,UTF-16BE,UTF-16LE不常用。

    739d6ae42262514879b4d10b8e1a12eb.png

    步骤 8 : 用FileInputStream 字节流正确读取中文

    为了能够正确的读取中文内容

    1. 必须了解文本是以哪种编码方式保存字符的

    2. 使用字节流读取了文本后,再使用对应的编码方式去识别这些数字,得到正确的字符

    如本例,一个文件中的内容是字符,编码方式是GBK,那么读出来的数据一定是D6D0。

    再使用GBK编码方式识别D6D0,就能正确的得到字符

    注: 在GBK的棋盘上找到的字后,JVM会自动找到在UNICODE这个棋盘上对应的数字,并且以UNICODE上的数字保存在内存中。

    c675625b4ed92b81f26efb9cb49a474f.png
    package 

    步骤 9 : 用FileReader 字符流正确读取中文

    FileReader得到的是字符,所以一定是已经把字节根据某种编码识别成了字符

    而FileReader使用的编码方式是Charset.defaultCharset()的返回值,如果是中文的操作系统,就是GBK

    FileReader是不能手动设置编码方式的,为了使用其他的编码方式,只能使用InputStreamReader来代替,像这样:

    new 

    在本例中,用记事本另存为UTF-8格式,然后用UTF-8就能识别对应的中文了。

    解释: 为什么中字前面有一个? 如果是使用记事本另存为UTF-8的格式,那么在第一个字节有一个标示符,叫做BOM用来标志这个文件是用UTF-8来编码的。

    390e39dc097f9b0bcd25ab1264abe629.png
    package 

    练习: 移除BOM

    如果用记事本根据UTF-8编码保存汉字就会在最前面生成一段标示符,这个标示符用于表示该文件是使用UTF-8编码的。

    找出这段标示符对应的十六进制,并且开发一个方法,自动去除这段标示符

    答案 :

    package 
    展开全文
  • 时间复杂度可以看作是机器学习算法针对输入大小执行速度快慢度量。时间复杂度总是相对于某些输入大小(例如n)给出。空间复杂度可以看作是...大O表示法:算法时间复杂度通常用大O符号表述,定义为T[n] = O(f...
  • 在,所有空格符号都由元符号“”(U + 2581)代替。 它允许将标记序列转换回文本,并恢复单词边界。 例如,短语Blazingly fast tokenization! 可以被标记为 ['▁Bl', 'az', 'ingly', '▁fast', '▁token', '...
  • 2016.4.24

    2016-04-24 19:39:57
    答案:main.o不知道hello_world函数定义在那个obj文件中,每个obj文件都有一个导出符号表,对于这个例子,hello_world.o的导出符号表中有hello_world这个函数,而main.o需要用到这个函数,可以想象就几个插槽一样
  • 3-修改新加pub.h内容,再make,果然问题出现了,make报告up to date,没有期望那样重编译main.o。 现在问题在于,main.d里某个.h文件改了,没有重新生成main.d。进一步说,main.d里给出每个依赖文件,任何...
  • python字符串格式方法

    2018-03-07 14:42:06
    C语言一样的用法:'my name is %s and age is %d' % ('lina', 18)1. 字符串格式化符号 %c 格式化字符及其ASCII码 %s 格式化字符串 %d 格式化整数 %u 格式化无符号整型 %o 格式化无符号八进制数 ...
  • C++指针专题(基础扫盲)

    千次阅读 多人点赞 2019-07-11 09:41:44
    让我们看看维基百科上定义:计算机中内存都是编址,每个地址都有一个符号,就家庭地址或者IP地址一样。指针,是一个无符号整数(unsigned int),它是一个以当前系统寻址范围为取值范围整数。声明指针和...
  • 一、ASCII 输出  为了使用下面的方法, 你必须包含头文件(译者注:在标准C++中,已经使用取 代,所有的C++标准头文件都是无后缀的。)。这是 的一个扩展集, 提供有缓 ... 使用方法是一样的. 看这个代码片段.
  • 6.15 我如何声明大小和传入的数组一样的局部数组? 6.16 如何动态分配多维数组? 6.17 有个很好的窍门,如果我这样写:intrealarray[10];int*array=&realarray[-1];我就可以把“array”当作下标从1 开始的数组。...
  • 算法复杂度

    2020-04-20 11:25:59
    时间复杂度可以看作是机器学习算法针对输入大小执行速度快慢度量。时间复杂度总是相对于某些输入大小(例如n)给出。 空间复杂度可以看作是执行...大O表示法:算法时间复杂度通常用大O符号表述,定义为T[n]...
  • 《你必须知道495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    3.21 “无符号保护”和“值保护”规则区别在哪里? 42 第4章 指针 45 基本指针应用 45 4.1 指针到底有什么好处? 45 4.2 我想声明一个指针并为它分配一些空间,但却不行。这些代码有什么问题呢?char ...
  • 而在符号运算中表现卓越Maple与Mathematica两个软件则只提供了对矩阵数值运算弱支持,并且难以实现与外部应用程序混合编程。MatCom与MATFOR则是提供了大量矩阵运算函数库用于应用程序二次开发,与MATLAB...
  • 3.21 “无符号保护”和“值保护”规则区别在哪里? 42 第4章 指针 45 基本指针应用 45 4.1 指针到底有什么好处? 45 4.2 我想声明一个指针并为它分配一些空间,但却不行。这些代码有什么问题呢?char ...
  • Redis原理分析(一)

    2019-01-26 14:10:50
    在C语言中,字符串的结尾是以NULL(0x\0)作为结束符号,但是在redis里面,如果C语言一样的话,如果需要获取某字符串,需要进行数组的遍历扫描,这样的时间复杂度为O(n),这样Redis表示我受不起。 所以Redis自己...
  • 期末考快到了,有些学生因为没有理解数学概念,复习上会遇到困难。...家长不妨让孩子记住,符号方向就是鳄鱼嘴巴一样,当然越大越好吃!2、巧背九乘法口诀九乘法口诀经常记不住?其实只要在...
  • o 7.12 我如何声明大小和传入的数组一样的局部数组 ? o 7.13 我该如何动态分配多维数组 ? o 7.14 有个灵巧的窍门: 如果我这样写 int realarray[10]; int *array = &realarray[-1]; 我就可以把 ``array" 当作...
  • 使用keil c51 v7.50 + proteus 6.7 可以使用仿真器一样调试程序,可以完全 仿真单步调试,进入中断等各种调试方案。 Proteus 与其它单片机仿真软件不同是,它不仅能仿真单片机CPU 工 作情况,也能仿真单片机...
  • 数组区别就是去掉前边@符号 let arr = ["haha","lala"] print(arr) // 遍历每一个元素 for a in arr{    print(a)   } // OC 一样打印 print(arr as NSArray) // //**数组使用[] 定义,这一点于O
  • 因为只是要写个脚本下数据,o(T.T)o,所以就浅尝辄止下下。只是需要用到用法用下。 注: Cygwin环境下,由于是模拟环境所以有些写法和...要注意是,首先书写不能在C++和Java中那么随意,运算符号什么...
  • libev :功能齐全,高性能时间循环,轻微地仿效libevent,但是不再libevent一样有局限性,也修复了它一些bug。 libevent :事件通知库。 libhv:跨平台事件循环库。 libuv :跨平台异步I/O。 promise-...
  • 查找元素问题

    2010-12-19 13:39:00
    假设有一个无序表存放有1亿个32位无符号整数,怎样快速判断一个...把这些数字都看成字符串,查找字典一样查找数字。这样查找复杂度是o(1),最多查找32步就可以作出判断了。 2 有没有比1更好方法呢?
  • 入门学习Linux常用必会60个命令实例详解doc/txt

    千次下载 热门讨论 2011-06-09 00:08:45
    umount 命令是mount命令的逆操作,它的参数和使用方法和mount命令是一样的。Linux挂装CD-ROM后,会锁定CD—ROM,这样就不能用CD- ROM面板上的Eject按钮弹出它。但是,当不再需要光盘时,如果已将/cdrom作为符号链接...
  • Linux C 编程一站式学习.pdf

    千次下载 热门讨论 2010-11-24 01:27:27
    本书可以替你节省时间,但不能替你思考,不要指望看小说一样走马观花看一遍就能学会。 内容预览: 历史 前言 I. C语言入门 1. 程序基本概念 1. 程序和编程语言 2. 自然语言和形式语言 3. 程序调试 4. 第一个...
  • Unix/Linux 编程实践教程.PDF

    千次下载 热门讨论 2010-09-03 18:34:12
    2.7 提高文件 I/O 效率方法:使用缓冲 2.7.1 缓冲区大小对性能影响 2.7.2 为什么系统调用需要很多时间 2.7.3 低效率 who2.c 2.7.4 在 who2.c 中运用缓冲技术 2.8 内核缓冲技术 2.9 文件读写 2.9.1 ...
  • C#微软培训教材(高清PDF)

    千次下载 热门讨论 2009-07-30 08:51:17
    17.1 .Net 框架结构提供 I/O 方式 .215 17.2 文件存储管理 .217 17.3 读 写 文 件 .222 17.4 异步文件操作 .227 17.5 小 结 .234 第十八章 高 级 话 题 .235 18.1 注册表编程 .235 18.2 在 C #代码...
  • awesome-python 是 vinta 发起维护 Python 资源列表,内容包括:Web 框架、网络爬虫、网络内容提取、模板引擎、数据库、数据可视化、图片处理、文本处理、自然语言处理、机器学习、日志、代码分析等。由「开源前哨...

空空如也

空空如也

1 2 3 4
收藏数 61
精华内容 24
关键字:

像o一样的符号