文章目录

  • Central Processing Unit 中央处理单元 简称CPU
      • 汇编语言的组成
      • Cpu对存储器的读写
      • CPU与其他存储芯片的导线-总线
      • 存储器
      • 内存地址空间 书中11页 作者对其作出了很好的解释
    • 寄存器
      • 通用寄存器 兼容8位寄存器
      • 注意:
      • 物理地址
      • 16位寄存器
      • 8086CPU的物理地址
      • 段的概念 书中24页
      • 段寄存器 书中25页
      • 书中28页将CS配合IP寻址 查询 的具体图解
      • 转移指令 修改CS IP 的值
      • 书中34对jmp做了图文并茂的解释
  • 实验一:CPU 的debug使用
  • 第三章
    • 内存中字的存储
      • DS和[address]书中48页
      • 字的传送
      • mov add sub
      • 书中52验证了mov [0] cs
      • 数据段
      • 栈 后进先出
      • CPU 栈机制
      • 栈超界
      • push 和 pop 指令 书中64页
      • 书中65页问题3.8将栈操作写的很完善
    • 栈段
    • 代码练习 书中78页
      • 段结束 程序结束 程序返回
      • 编译asm文件过程 书中 第84页
      • 连接 obj -> exe
      • 简化编译连接 注意加上 ';'。
      • cmd命令行是怎么执行程序的 书中90页
      • 关于DOSBOX的快捷键操作
      • DEBUG追踪exe执行过程
  • 第五章 [BX]和loop命令
    • [bx]和内存单元
    • Loop循环
    • 通过编译连接的asm文件 对[]偏移地址的解释错误
    • 段前缀
    • 书中120页给出了loop循环很好的实例
  • 第六章 包含多个段的程序
    • 在代码中使用数据
    • 标记程序开始部分 类似于smali语言中的 .prologue 书中126页
    • 自定义段 书中130页
  • 第七章
    • or and 指令
    • 书中139页介绍了ASCII从键盘到显示器过程
    • 字符串数据
    • 转换大小写案例
    • [bx+idata]进行数组处理 简化上面的程序
    • SI DI 与bx功能相似 不能分成两个8位寄存器 书中147页
    • 寻址方式的灵活运用 书中152页
    • 为了培养我们汇编中数组的概念 书中153页
    • 循环嵌套
    • 改进之-栈存储数据(节省寄存器的使用数量)
  • 第八章 数据处理
      • 使用规则 mov ax [...]
      • 机器指令处理的数据在什么地方
      • 数据位置的表达
      • 寻址方式
      • 指令处理的数据长度
      • div指令 除法指令
      • 伪指令dd ((dword)double word 双字型 即四个字节 32位)
      • dup(两份) 配合dd 进行数据重复 书中172页
    • 试验七 书中173页 请认真完成!!
  • 第九章 转移指令原理
    • 操作符 offset 获取标号的偏移地址
    • 我们先复习一下补码 书中329页
    • 求0-9的补码
    • 转移地址在内存中的jmp指令
    • jcxz指令 条件转移指令(短指令)
    • loop指令前面讲过了
    • 书中189页 试验8.9部分以后再看
  • 第十章 Call和Ret指令
    • Call指令
    • call 和 ret 配合使用
    • mul指令 乘法指令
    • 参数和结果的传递
    • 批量数据传递
    • 试验10-编写子程序 书中206页
  • 第十一章 标志寄存器
    • ZF标志 零标志位 zero flag
    • PF标志 奇偶标志 parity flag
    • SF标志 符号标志位 symbol flag
    • CF标志 进位标志 carry flag
    • OF标志 溢出标志位 overflow Flag
    • adc指令 add +carry 带进位的加法指令
    • sbb指令 subtraction+borrow 带进位的减法指令
    • cmp指令 compare 比较指令
    • 书中225页进行了一通cmp分析
    • 检测比较结果的条件转移指令
    • DF标志 和 串传送指令
    • 实现内存的传送
    • pushf 和 popf 针对标志寄存器压弹栈 书中234页
    • Debug中的flag 标记
    • 试验11 书中234页
  • 第十二章 内中断
    • 内中断的产生
    • 中断类型
    • 中断向量表:中断处理程序入口地址列表
    • 中断过程
    • iret指令和中断处理程序
    • 除法溢出错误
    • do0 修改 除法溢出的错误提示
    • 安装 do0
    • 编写do0程序
    • 改进do0
    • 设置中断向量
    • 单步中断 类似Debug的t命令单步调试
    • 响应中断的特殊情况
    • 试验12 编写0号中断处理程序 书中251页
  • 第十三章 int指令:内中断之一
    • 书中253页 编写一个中断程序

Central Processing Unit 中央处理单元 简称CPU

汇编语言的组成
  • 汇编指令:机器码助记符 有对应机器码

  • 伪指令:没有对应机器码 由编译器执行 计算机不执行

  • 其他符号:如+ - * / 等 又编译器识别 计算机不执行

  • 存储器 = 128存储单元 = 128Byte

  • Byte = 8bit =一个内存单元

  • 1bit = 1个二进制位 一个bit只能表示一个开关量,例如 l代表“开关闭合”,0代表“开关断开”。

Cpu对存储器的读写
  • 存储单元信息(地址信息)
  • 器件选择 读或写的命令(控制信息)
  • 读或写的数据(数据信息)
CPU与其他存储芯片的导线-总线
  • 地址总线 发出地址信息

  • 控制总线 发出内存读命令 选中存储芯片 通知他从中读取数据

  • 数据总线 将读取到的数据送入CPU

  • 地址总线 一根线表示一位 N根表示地址总线宽度为N,寻址范围为0-2^N。

  • 数据总线 总线宽度决定了传输的速度,8根表示一个1Byte,16根表示2Byte.

  • 控制总线 总线宽度决定了CUP对外部器件的控制能力

存储器
  • 随机存储器
  • 只读存储器
  • BOIS(Basic Input?output System,基本输入/输出系统)
  • 接口卡上的RAM
内存地址空间 书中11页 作者对其作出了很好的解释

CUP通过总线于各个物理存储器相连,将他们看作一个个存储器单元,他们分别占据一个地址段,CUP在这段地址空间读写数据 实际上就是在相应的物理存储器上读写数据。而汇编语言就是面对的内存地址空间。

寄存器

CPU内部

  • 运算器:进行信息计算
  • 寄存器:进行信息存储
  • 控制器:控制各器件进行工作
  • 内部总线:连接各个器件 在他们工作时进行数据传递
通用寄存器 兼容8位寄存器
  • AX : 分AH和AL 书中16页介绍了 AX 20000(4E20) AH 78(4E) AL 32(20)
  • BX : 分BH和BL
  • CX : 分CH和CL
  • DX : 分DH和DL
  • ADD AX ,BX AX为16位 最多存4位16进制 最高位去掉 即0000H
  • ADD AL ,BL AL为8位 最多存2位16进制 最高位去掉 00H
注意:
  • MOV AX,BL
  • 8位寄存器与16位寄存器之间传递数据
  • MOV BH,AX
  • 16位寄存器与8位寄存器之间传递数据
  • MOV AL,2000
  • 8位最多存储255的数值
  • MOV AL,100H
  • 不要将一个高于8位的数加到8位寄存器
物理地址

内存单元位线性空间 拥有唯一地址 即为物理地址

16位寄存器
  • 运算器一次处理16位数据
  • 寄存器最大宽度16位
  • 寄存器和运算器通路位16位
8086CPU的物理地址
  • 提供两个16位地址,段地址 偏移地址
  • 通过内部总线送入地址假发器
  • 地址加法器合成为一个20位物理地址
  • 地址加法器送入BIOS
  • BOIS将20位物理地址送入地址总线
  • 地址总线送到储存器

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

下图对物理地址左移做了很详细的总结

那么 16位地址 * 16 其实是乘10H,也可以说是16位地址转成10进制成16。最简单的方式就是16位地址左移1位

本质:基础地址+偏移地址  = 物理地址基础地址 = 段地址 * 16

书中22对其本质做出了生动的解释

段的概念 书中24页
  • 段地址 大小一定为16的倍数
  • 偏移地址最大为16位 则最大寻址能力为64kb
段寄存器 书中25页
  • 8086CPU提供四个段寄存器CS DS SS ES
  • CS 代码段寄存器
  • IP 指令指针寄存器
书中28页将CS配合IP寻址 查询 的具体图解

当进入指令缓冲器 即为读取一条指令 IP 值自动增加并读取下一条指令根据第一条指令的大小增加值

复位或者加电启动 CS=FFFFH IP=0000H FFFF0H即为8086PC启动执行的第一条指令

转移指令 修改CS IP 的值
  • jmp段地址:偏移地址
  • jmp 3:0B16 CS= 0003H IP= 0B16H 即从00B46H读取指令
  • jmp 2AE3:3 CS= 2AE3 IP= 0003H 即从2AE33H读取指令
  • jmp bx 等同于 mov IP,ax CS不变 BX赋值给IP
书中34对jmp做了图文并茂的解释

jmp 1000:3 就是跳转到1000*16+0003H = 10003H处读取指令。

实验一:CPU 的debug使用

先找个引路篇-安转篇https://blog.csdn.net/try2find/article/details/39619999

以及debug的命令行使用 https://blog.csdn.net/liuer2004_82/article/details/52638516#t2

第三章

内存中字的存储
  • 字单元:存放一个字型数据(16位)的内存单元,两个连续的内存单元
  • 高地址存字型数据的高位字节 低地址存字型数据的地位字节
  • 地址单元和地址子单元:每个地址单元包含一个高位字节单元和一个低位字节单元
DS和[address]书中48页
  • mov al,[0] 表示: mov 寄存器名,内存单元地址
  • […] 表示内存单元 […]中的0表示内存单元的偏移地址。
  • mov ds,bx ds会被默认取值 作为段地址 所以在调用mov al,[0]前必须给值ds.
  • mov ds,1000H 为非法操作 数据不能直接送入段寄存器 即ds 需要先mov bx,1000H
字的传送

书中51页对字的传送做了图文并茂的介绍 表3.2

mov add sub
  • mov 寄存器,数据 mov ax,8
  • mov 寄存器,寄存器 mov ax,bx
  • mov 寄存器,内存单元 mov ax,[0]
  • mov 内存单元,寄存器 mov [],ax
  • mov 段寄存器,寄存器 mov ds,ax
书中52验证了mov [0] cs

我学会debug指令 r,t,d查看 a修改

数据段

数据段:将一组长度为N(N<=64KB),地址连续,起始地址为16的倍数的内存单元当做专门存储数据的内存空间,即为数据段。

各寄存器初始值:CS = 2000H,IP = 0,DS = 1000H,AX = 0,BX = 0;

栈 后进先出
CPU 栈机制
  • 如何确定栈空间?
  • 如何确定栈顶?
  • 段寄存器SS 存放栈顶栈地址
  • 寄存器SP 存放偏移地址
  • 任意时刻 SS:SP指向栈顶 SS 为段寄存器 SP为 偏移地址
栈超界

栈满push 栈空pop都会造成栈超界问题
8086CPU并没有给出解决方法 需自己注意

push 和 pop 指令 书中64页
//基本操作
mov ax,1000H
mov ss,ax   ;设置栈的段地址 值必须由ax传递
push [0]    ;将1000:0处的字压入栈中
pop [2]     ;出栈 出栈的数据送入1000:2中
书中65页问题3.8将栈操作写的很完善

push时:CPU操作:先改变SP:SP-2 后向SS:SP处传送

pop时: CPU操作:先读取SS:SP处的数据,后改变SP :SP+2

栈段
  • DS 内存区间 段地址
  • CS 代码段 段地址
  • SS 栈 段地址
-r ds
:1000
-d ds:0 ;查看1000:0开始的内存区间 128字节-r ds
:1000
-d ds:10 18 ;查看1000:0~1000:18 中的内容-d cs:0     ;查看当前代码段中的指令代码-d ss:0     ;查看当前栈中的内容

E 直接修改内存
U 显示代码 以汇编的形式
A 汇编指令修改内存

-r ds
:1000
-e ds:0 11 12 33 11 44 ;在从1000:0开始的内存区间写入数据-u cs:0  ;以汇编指令的形式,显示代码段中的代码,0是段地址-r ds
:1000
-a ds:0     ;以汇编指令的形式,向1000:0开始的内存单元写入指令
代码练习 书中78页
assume cs:codesg;‘假设’编译程序将段寄存器和某个具体的段相关联
codesg segment  ;与codesg ends 成对使用 定义一个代码段,名称为‘codesg’mov ax,0123Hmov bx,0456Hadd ax,bxadd ax,axmov ax,4c00Hint 21H
codesg endsend ;汇编程序结束的标志
段结束 程序结束 程序返回
目的 相关指令 指令性质 指令执行者
通知编译器一个段结束 段名 ends 伪指令 编译时 编译器
通知编译器程序结束 end 伪指令 编译时 编译器
程序返回 mov ax,4c00H int 21H 汇编指令 编译时 由CPU行
编译asm文件过程 书中 第84页

首先需要一套工具 这边提供下载链接 https://blog.csdn.net/wybliw/article/details/53259602

设置完环境后打开dosbox 输入Masm 输入文件路径 一路enter会得到 .OBJ后缀文件 而实际上会得到三个文件

  • 目标文件 obj
  • 列表文件 lst
  • 交叉引用文件 crf
连接 obj -> exe

输入Link 然后输入文件名 一路enter 生成 exe

简化编译连接 注意加上 ‘;’。
  • masm newone.asm;
  • link newone.obj;
cmd命令行是怎么执行程序的 书中90页

关于DOSBOX的快捷键操作

https://blog.csdn.net/lovefengruoqing/article/details/79009456

DEBUG追踪exe执行过程
  • debug newone.exe 可跟踪执行
  • CX 指定机器码字节数
  • PSP 为DOS创建程序前缀 与被加载程序通信 256字节
  • 可用段地址为 PSP 段地址+偏移地址为 SA+10H:0
  • U命令查看汇编命令
  • int 21H 使用 P命令结束

第五章 [BX]和loop命令

[bx]和内存单元
  • [bx]同样表示一个内存单元 偏移地址为bx
  • loop 循环指令
  • ‘()’表示一个寄存器或者一个内存单元中的内容
  • ‘()’可用元素的种类型 1 寄存器 2 段寄存器 3 内存单元物理地址(20位)
  • ‘()’表示两种数据类型 1 字型 2字节型 (al) = (20000H)取字节型 (ax)=(20000H) 20000H取字型
    -idata 表示常量
Loop循环
mov cx ,循环次数
s: 循环执行程序块loop s
通过编译连接的asm文件 对[]偏移地址的解释错误

使用[bx]间接传递偏移地址

mov ax , 2000H
mov ds , ax         ;段地址2000H送入ds
mov bx , 0          ;偏移地址0送入bx
mov al , [bx]       ;ds:bx的送入al

或者

mov al , ds:[0]
段前缀
  • ds 默认段地址
  • cs 代码段地址
  • ss 栈段地址
  • es 显存段地址
书中120页给出了loop循环很好的实例

第六章 包含多个段的程序

在代码中使用数据
assume cs:code   ;与系统cs相关联 固定写法
code segment    ;代码段 名称 'code' dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h  ;声明字型数据mov bx,0                ;赋值语句mov ax,0                ;赋值语句mov cx,8                ;循环8次
s:add ax,cs:[bx]            ;(ax) =((cs*16)+bx)add bx,2                ;偏移地址+2loop s                  mov ax,4c00h            ;类似于return 固定写法int 21h
code endsend                         ; 代码段结束标记  固定写法
标记程序开始部分 类似于smali语言中的 .prologue 书中126页
assume cs:code   ;与系统cs相关联 固定写法
code segment    ;代码段 名称 'code' dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h  ;声明字型数据start:  mov bx,0                ;赋值语句mov ax,0                ;赋值语句mov cx,8                ;循环8次s:add ax,cs:[bx]            ;(ax) =((cs*16)+bx)add bx,2                ;偏移地址+2loop s                  mov ax,4c00h            ;类似于return 固定写法int 21hcode ends
end start                    ; 代码段结束标记  固定写法
自定义段 书中130页
  • 一个段的数据段可以由段名表示,如:data:6表示’0cbah’
  • 这也是JAVA思想的雏形啊
  • CPU 将 cs指向code ds指向data ss指向stack(可以这样理解)
assume cs:code,ds:data,ss:stack          ;关联系统段地址 :固定写法data segment       ;自定义段 datadw 0123h,0456h,0789h,0abch,0defh,0cbah,0987h          ;16字节内存单元
data ends           ;段结束stack segment           ;   自定义栈 stackdw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0                    ;16字节内存单元
stack ends          ;段结束code segment        ;自定义代码段  codestart:mov ax,stack                         ;start 开始标记  stack段地址给寄存器axmov ss,ax                                ;ax赋给栈段地址   mov sp,20h                          ;设置栈顶ss:sp 指向stack:20mov ax,data                         ;data段地址给寄存器axmov ds,ax                             ;ds 指向 data mov cx,8                                ;设置循环次数8s:push [bx]                             ;将ds:[bx]的值入栈,也就是data:0~15的16个字型数据add bx,2                               ;bx 自加 2loop                                    ;循环标志 固定写法mov bx,0                              ;将bx置空mov cx,8                              ;循环标志 固定写法s0:pop [bx]                               ;将栈stack依次出栈 赋值给 ds:[bx]add bx,2                                ;bx 自加 2loop s0                             ;循环标志 固定写法mov ax,4c00h                          ;结束标志 固定写法int 21h
code ends                               ;代码段结束标记end start                               ;程序结束标记

第七章

or and 指令

and: 与指令 同为1 则为1
or : 只要有1 则为1

mov al 1100100B
add al 1000000B
//执行和结果为  10000000B
mov al 1000111B
or  al 1110111B
//执行结果为 1110111B
书中139页介绍了ASCII从键盘到显示器过程

ASCII码表 http://ascii.911cha.com/

字符串数据

这边先介绍一下 db dw dd

  • db定义字节类型变量,一个字节数据占1个字节单元,读完一个,偏移量加1
  • dw定义字类型变量,一个字数据占2个字节单元,读完一个,偏移量加2
  • dd定义双字类型变量,一个双字数据占4个字节单元,读完一个,偏移量加4
转换大小写案例

这里有意思的是

  • 大写转小写 即 and 11011111B 也就是-20H 也就是第五位置0 大写转大写无变化
  • 小写转大写 即 and 00100000B 也就是+20H 也就是第五位置1 小写转小写无变化
assume cs:codesg,ds:datasgdatasg segmentdb 'BaSiC'db 'iNfOrMaTiOn'
datasg endscodesg segmentstart:mov ax,datasgmov ds,axmov bx,0mov cx,5s:mov al,[bx]          ;取出ds:bx所指的第一个字母and al,11011111B   ;将第五位置0 就是-20H mov [bx],al       ;将值返还给ds:[bx]inc bxloop s            mov bx,5               ;从ds:5开始指向information的第一个字母 mov cx,11s0:mov al,[bx]         or al,00100000B  ;将第五位置1 就是+20H mov [bx],alinc bxloop s0             mov ax,4c00hint 21hcodesg ends
end start
[bx+idata]进行数组处理 简化上面的程序
mov al,[5+bx]
mov [5+bx],al
  • C语言:a[i],b[i]
  • 汇编语言:0[bx],5[bx] 那这里的 0 5 代表的就是 数组的首地址了 而c语言用数组名表示
SI DI 与bx功能相似 不能分成两个8位寄存器 书中147页
mov ax ,[bx][si]
//等同于
mov ax,[bx=si]
//描述为
(ax) = (ds*16 + bx + si)
寻址方式的灵活运用 书中152页
  • [idata]
  • [bx]
  • [bx+idata]
  • [bx+si]
  • [bx+si+idata]
为了培养我们汇编中数组的概念 书中153页

定义如下数据段 6个字符串 等同于下图 的一个

datasg segment;注意每个字符被扩展为16位db  '0. file        'db  '1. edit        'db  '2. search      'db  '3. veiw        'db  '4. options     'db  '5. helps       '
datasg ends

循环嵌套

最终:是将datasg数组中的数据全部大写

datasg segment;注意每个字符被扩展为16位db  'fil              'db  'edi              'db  'sea              'db  'vei              '
datasg endsmov ax,datasg
mov ds,ax
mov bx,0        ;ds:bx 指向datasg
mov cx,4        ;循环次数4行s0:mov si,0     ;外层循环 第一行 当si=3退出循环mov cx,3     ;循环次数3列s: mov al,[bx+si]    ;内层循环 ds:[bx][si]  理解为 第bx行 第si列and al,11011111b    ;第五位置0 也就是-20H 也就是 小写 -> 大写mov [bx+si],al      ;inc si              si加1loop sadd bx,16               ;外层循环 +16 即+10H 即换行
loop s0
改进之-栈存储数据(节省寄存器的使用数量)

用栈的方式暂时保存cx的值

datasg segment;注意每个字符被扩展为16位db  'fil              'db  'edi              'db  'sea              'db  'vei              '
datasg endsstacksg segmentdw 0,0,0,0,0,0,0,0
stacksg segmentcodesg segmentstart:mov ax ,stacksg      mov ss,axmov sp,16              ;ss:sp 指向 stacksg:10Hmov ax,datasg            mov ds,axmov bx,0               ;ds:bx 指向 datasg:0mov cx,4                   s0:   push cx               ;入栈 cx mov si,0             mov cx,3s:    mov al,[bx+si]       ;(al) = (ds*16+bx+si) 也就是[bx][si] bx行si列and al,11011111b       ;改成大写mov [bx+si],al        ;(ds*16+bx+si) = (al)inc si                ;si自加1loop sadd bx,16               ;换行pop cx               ;出栈 给cxloop s0mov ax,4c00hint 21hcodesg endsend start

第八章 数据处理

  • 处理数据在什么地方?

  • 要处理的数据有多长?

  • reg:寄存器 ax bx cx dx al ah bl bh cl ch dl dh cl ch sp bp si di

  • sreg:段寄存器 ds cs ss es

使用规则 mov ax […]
  • bx si bp di 可用于内存单元寻址
  • bx si bp di 只能单独出现,且 bx与bp,si与di不能组合使用
  • []中使用bp 默认使用段寄存器 ss 即 ss*16+bp
机器指令处理的数据在什么地方
机器码 汇编指令 指令执行前数据的位置
8E1E0000 mov bx,[0] 内存,ds:0单元
89c3 mov bx,ax CPU内部,ax寄存器
BB0100 mov bx,1 CPU内部,指令缓冲器
数据位置的表达
  • 立即数(idata)
  • 寄存器
  • 段地址(SA)和偏移地址(EA)
  • 存放段地址的寄存器 如:mov ax ds:[bx]
寻址方式

指令处理的数据长度
  • ax 字单元
  • al 字节单元
  • mov byte ptr ds:[0],1 字节单元
  • mov word ptr ds:[0],1 字单元
  • [bx].idata [bx].idata[si] bx定位结构体 idata定位数据项 si定位数组元素 (书中169页)
div指令 除法指令
  • 除数:8位和16位 在一个reg或内存单元中
  • 除号前面位被除数,后面为除数
  • 被除数:默认放在AX或者DX和AX中 除数8位则被除数16位 除数16位则被除数32位,由DX(高16位)和AX存放(底16位)
  • 结果:除数8位 AL存商 AH存余数 除数16位 AX存商 DX存余数

实例

div word ptr es:[0]
(ax) = [(dx)*10000H+(ax)]/((es)*16+0)的商   //注意这里是10000H
(dx) = [(dx)*10000H+(ax)]/((es)*16+0)的余数div byte ptr ds:[0]
(al) = (ax)/((ds)*16+0)的商
(ah) = (ax)/((ds)*16+0)的余数

实例计算 100001/100

mov dx,1
mov ax,86a1h
mov bx,100
div bx

根据公式一:
100 = 64H

  • (ax) = [1*10000H+ax]/100 = 186a1H/64H = 03e8h
  • (dx) = [1*10000H+ax]%100 = 186a1H%64H = 1
伪指令dd ((dword)double word 双字型 即四个字节 32位)
  • db 00H 2个8位
  • dw 0000H 2个byte
  • dd 00000000H 2个word
dup(两份) 配合dd 进行数据重复 书中172页
  • db 3 dup (0) == db 0,0,0
试验七 书中173页 请认真完成!!

答案地址 https://blog.csdn.net/love_jing_forever/article/details/53204818

第九章 转移指令原理

定义:可以修改IP,或同事修改CS和IP的指令统称为转移指令。

转移行为:

  • 段内转移 只修改IP jmp ax
  • 段间转移 同事修改 CS IP jmp 1000:0

对IP修改范围不同

  • 短转移 对IP修改范围 -128~127
  • 近转移 对IP修改范围 -32768~32767

指令分类

  • 无条件转移指令 jmp
  • 条件转移指令
  • 循环指令 loop
  • 过程
  • 中断
操作符 offset 获取标号的偏移地址
start:mov ax ,offset start  ;相当于mov ax ,0s:mov ax ,offset s      ;相当于 mov ax s

jmp指令并不需要转移的目的地址 只需要转移的位移

assume cs:codesg
codesg segmentstart:mov ax,0      jmp short s ;short 表示范围在 -128~127之间 即‘段内短转移’ add ax,1  s:inc ax
codesg endsend start
我们先复习一下补码 书中329页
  • 8位无符号数 00000000B~11111111F 共255个数

  • 8位有符号数

  • 10000000B~11111111F -127~127 共254个数 注意:10000000B不算-0没有意义

  • 最高位为1 表示负数

  • 整数补码取反加1或,为其对应负数的补码,负数补码取反后加1,位其绝对值

  • 1的补码:11111111B,表示-1

  • -1的补码:00000001B,其绝对值为1.

  • 补码计算法定义:非负数的补码是其原码本身;负数的补码是其绝对值的原码最高位符号位不变,其它位取反,再加1。

  • 模定义:一个负整数与其补码的和。

整理下对补码的知识

求0-9的补码
0000H-0009H
因为指定jmp short 转成二进制:
00000000B-00001001B
应为没有减法器 所以理解为加法
00000000B+(-00001001B)
也就是求-9(10001001B)的补码
10001001B 取反且首位不变(11110111B)
即F7H
  • jmp near ptr 标号(IP) = (IP)+16位位移
  • jmp far ptr 标号 段间转移 远转移 (CS)=标号所在段的段地址;(IP)=标号在段中的偏移地址
转移地址在内存中的jmp指令
  • jmp word ptr ds:[0] 将内存单元中的存放的赋给 偏移地址 (IP) = (ds:[0])
  • jmp word ptr [bx]将内存单元中的存放的赋给 偏移地址 (IP) = ([bx])
  • jump dword ptr 内存单元地址(段地址) (CS) = (内存单元地址+2) (IP) = (内存单元地址)
mov ax ,0123H
mov ds:[0],ax
mov word ptr ds:[2],0
jmp dword ptr ds:[0]
//(CS)=0,(IP)=0123H,CS:IP指向0000:0123
jcxz指令 条件转移指令(短指令)

JCXZ CX: 为零时转移

格式:jcxz 标号
用高级语言描述:if (cx == 0) jmp short 标号     ;------> 当cx= 0 转移到标号处elsenext                ;------>当cx != 0 程序什么也不做,继续向下执行
(短转移,通过位移进行转移,IP修改范围-128~127
loop指令前面讲过了
书中189页 试验8.9部分以后再看

第十章 Call和Ret指令

  • call和ret都是转移指令 都可修改IP 或同时修改CS和IP
  • ret 修改IP 实现近转移 相当于 pop IP
  • retf 修改SS和IP 实现远转移 相当于 POP IP POP CS

实例:

assume cs:codesg
stack segment
db 16 dup (0)  ;申请一个16字节的空间
stack endscode segmentmov ax,4c00hint 12h
start: mov ax,stack     ;代码开始部分mov ss,ax        mov sp,16mov ax,0push cs      push axmov bx,0retf        cs:IP指向 cs:ax即 cs:0000H;代码第一行mov ax,4c00h
code endsend start
Call指令
  • 将当前IP或者CS和IP压入栈中
  • 转移
  • 不能实现短转移 范围2个有符号字节

call 标号

汇编表示: 入栈IP后

(SP) = (SP)-2
((ss)*16+(sp))=(IP)  将IP对应的值存入ss:sp中  sp偏移向上2个字节
(IP)=(IP)+16
push IP
jmp near ptr 标号    ;对应(IP)=(IP)+16  就是跳过一行
```c
cal far ptr 标号 段间转移
汇编表示:入栈CS 和 IP后

push CS
push IP
jmp far ptr 标号 cs:ip指向 标号处


call 16位reg
汇编表示:```c
push IP
jmp 16位 reg   ; 直接跳转到ss:reg位置

call word ptr
汇编表示: 跳转到 标号处 SP+2

push IP
jmp word ptr 内存单元地址

call dword ptr
汇编表示: 跳转到 标号处 SP+4

push CS
push IP
jmp word ptr 内存单元地址
call 和 ret 配合使用
  • 子程序:具有一定功能的程序。
  • call:调用子程序 并将IP压入栈中
    ret:返回子程序 POP IP弹栈后 调用cs:ip处的代码 即 call的下一行。
mul指令 乘法指令
  • 想成两数 必须同时为16位或8位
  • 8位时 一个默认放在AL中,另外一个放在8位reg或者内存单元中
  • 16位 一个默认放在AX中,另一个放在16位reg或者内存单元中

对于结果:

  • 8位乘法 结果默认放在AX中
  • 16位乘法 结果高位放在DX,低位放在AX中
mul byte ptr ds:[0]
;含义: (ax) = (al)*((ds)*16+0);   (ax) = (al)*(ds:bx)mul word ptr [bx+si+8]
;(ax) = (ax)*((ds)*16+(bx)+si+8)结果的底16位
;(dx) = (ax)*((ds)*16+(bx)+si+8)结果的高16位计算100*10
分析:100和10 都小于255  可以做8位乘法mov al ,100mov bl ,10mul bl结果:(ax) = al*bl = 1000 = 0e38H计算10000*100100小于255,10000大于255,所以做16位乘法mov ax,100mov bx,10000mul bx结果: ax*bx = F4240 = 11110100001001000000 =1111 0100 0010 0100 0000(ax) = 4240H dx = 0000 0000 0000 1111 = 0000FH
参数和结果的传递

子程序:也就java中的Util方法 或者普通方法

assume cs:codedata segmentdw 1,2,3,4,5,6,7,8       ;这边申请的是word 也就是一个字16位dd 0,0,0,0,0,0,0,0         ;这边申请的是dword 也就是一个双字32位data endscode segmentstart:mov ax,datamov ds,axmov si,0                ;ds:si 指向第一组word单元mov di,16             ;ds:di 指向第二组的dword单元;si di等同于bx  不能分成两个8位mov cx 8               ;循环8次s:mov bx,[si]          ;(bx) = ([ds:si])=([ds:0])=1call cube                ;假设bx = 8 mov [di],ax          ;([di]) = 0040H    低16位mov [di].2,ax           ;向后移动2个字节  高16位 add si,2                ;ds:si 指向下一个word单元add di,4              ;ds:di 指向下一个dword单元loop smov ax,4c00hint 21hcube:mov ax,bx          ;该方法被调用 因为bx小于255(FF) 用8位mul bx               ;(ax) = (al)*(bx) = 0*H*0008H =8 * 8 = 64 =0040Hmul bx             ;(ax) = (al)*(bx) = 04H*0040H =4 * 64 = 64 =0100Hret               ;返回调用处的下一行,即:mov [di],axcode endsend start
批量数据传递

作者告诉我们为什么定义字符串使用 db https://blog.csdn.net/weixin_42553435/article/details/80919722

assume cs:codedata segmentdb 'conversation'  ;存的byte字节 是顺序的 ;可以理解成 db 'c','o','n','v','e','r','s','a','t','i','o','n' 总共12个字符data endscode segmentstart:mov ax,datamov ds,axmov si,0mov cx,12call capitalmov ax,4c00hint 21hcapital:and byte ptr [si],11011111Binc siloop capitalretcode endsend start

编写子程序的标准

子程序开始: 子程序中使用的寄存器入栈子程序内容子程序中使用的寄存器出栈返回(ret,retf)
试验10-编写子程序 书中206页

第十一章 标志寄存器

  • 存储相关指令的执行结果
  • 位CPU执行指令提供行为依据
  • 控制CUP的工作方式

ZF标志 零标志位 zero flag
  • 记录指令执行的结果是否为0
  • 1则zf = 0 , 0则 zf = 1
  • 影响zf指令:add,sub,mul,div,inc,or,and
  • 不影响zf指令:mov push pop
mov ax,1
sub ax,1
//ax=0,zf =1
PF标志 奇偶标志 parity flag
  • 记录指令执行的结果 的bit位中1的个数是否为偶数,偶数则pf=1 奇数则pf=0
mov ax,1
add al,10
//ax=00001011B,zf =0
SF标志 符号标志位 symbol flag
  • 记录指令执行的结果 是否为负,为负数则sf=1 非负则sf=0
  • 当做无符号数计算 SF无意义
  • 只记录实际结果的正负 不记录逻辑结果的正负 (考虑溢出)
mov al,10000001B
add al,1
//结果:(al) = 10000010B
//SF=1
mov al,10000001B
add al,01111111B
//结果:(al) = 100000000B //溢出则 去掉最高位1 取00000000B = 00H
//SF=0 结果非负数
CF标志 进位标志 carry flag
  • 无符号位的计算中
  • 记录运算结果的: 1.最高有效位 2.更高位进位值 3.从更高位的借位值
  • 比如一个8位数 第7位位最高有效位 第8位即相对于最高有效位的更高位
  • 8位溢出后 由CF记录这个值
  • 97H-98H 将产生借位
mov al,98H
add al,al       ;98H*2 = 0130H执行后:(al) = 30H, CF = 1,,CF记录最高有效位的更高位的进位值
add al,al       ;30H*2 = 60H ,CF = 0
mov al,97H
sub al,98H      ;借位后即: (al) =  197H-98H = FFH ,CF=1,记录向更高位的借位值
sub al,al       ;(al) = FFH-FFH = 0H ,CF = 0
OF标志 溢出标志位 overflow Flag
  • OF只对有符号数有意义 计算出理想值进行比较 如8位范围-128~127
  • 8位有效范围:-128~127
  • 溢出OF =1
  • CF只对无符号数有意义
  • CPU 在执行指令时 会对数据分别做有符号和无符号的计算 并对CF OF分别赋值
mov al,98
add al,97  ;结果为::98+97 = 195;实际结果位 195 = C3H=11000011B//11000011B 为有符号数 //10111100B+1//10111101B  =-61
  • 对于无符号数:没有产生进位 CF = 0
  • 对于有符号数:产生溢出 OF = 1
mov al,0F0H     ; FOH 为有符号数    -16 //11110000//10001111+1//10010000add al,088H     ; 088H 为有符号数   -120//10001000//11110111+1//11111000 ;0F0H+ 088H 结果为 101111000//101111000  //110000111+1//110001000  -136 溢出;但是实际结果为//01111000  超界则去掉最高位//78H
  • 对于无符号数:没有产生进位 CF = 1
  • 对于有符号数:产生溢出 OF = 1
adc指令 add +carry 带进位的加法指令
adc ax,bx 实现功能:(ax) = (ax)+(bx)+CF mov ax,2
mov bx,1
sub bx,ax    ;(bx)<(ax) 产生借位:CF=1
adc ax,1     ;(ax)+1+CF = 2+1+1=4
sbb指令 subtraction+borrow 带进位的减法指令
cmp指令 compare 比较指令
  • 于减法指令,只是不保存结果
  • p指令执行后,将对标志寄存器产生影响
mov ax,8
mov bx,3
cmp ax,bx
//执行后:(ax)-(bx) =5, zf = 0,pf = 1,sf = 0,cf = 0,of =0;
书中225页进行了一通cmp分析
  • zf = 1 说明:ax = bx
  • zf = 0 说明:ax != bx
  • cf = 1 说明:ax < bx
  • cf = 0 说明:ax >= bx
  • cf = 0 并且 zf = 0 说明:ax > bx
  • cf = 1 或 zf =1 说明:ax <= bx
  • sf = 1 并且 of = 1 (ah) > (bh)
  • sf = 0 并且 of = 1 (ah) < (bh)
  • sf = 0 并且 0f = 0 (ah) >=(bh)
检测比较结果的条件转移指令
指令 含义 检测相关标志位
je(equal) 等于则转移 zf=1
jne 不等于 zf!=0
jb(below) 低于 cf=1
jnb 不低于 cf=0
ja(above) 高于 cf = 0 并且 zf = 0
jna 不高于 cf = 1 后者 zf = 1
cmp ah,bh
je s            ;如果(ah)= (bh) 其实只要ZF = 1 就执行 :跳转到 s  否则向下执行
add ah,bh
jmp short ok
s:add ah,ah
ok:...
DF标志 和 串传送指令
  • DF标志:direction flag 方向标志
  • 串处理指令:控制每次操作后 si di 的增减
  • df = 0 每次操作后 si di 递增
  • df = 1 每次操作后 si di 递减
  • movsb(byte) 描述:mov es:[di],byte ptr ds:[si] df=0: di si 加1 ,df=0: di si 减1
  • movsw(word) 描述:mov es:[di],byte ptr ds:[si] df=0: di si 加2 ,df=0: di si 减2
  • cld指令 将df置1
  • std指令 将df置0
  • rep movsb 配合movsb 和 movsw 使用 实现循环 汇编描述:
s:movsbloop s
实现内存的传送
data segmentdb 'Welcome to masm!'db 16 dup (0)
data endscode segmentmov ax ,datamov ds,axmov si,0      ;ds:si 指向 data:0mov es,ax   mov di:16       ;es:di 指向 data:0010Hmov cx,16        cld             ;df=0 正向传送rep movsb
code ends
pushf 和 popf 针对标志寄存器压弹栈 书中234页

检测点11.4 记得这是存的flag 是一个16位的数

下面指令执行后,(ax)=0045hmov ax,0            ;(ax)=0push ax             ;将(ax)入栈popf                ;将flag寄存器的所有为都初始化为0.因为它们使用的是同一个栈结构。mov ax,0fff0h       ;(ax)=0fff0Hadd ax,0010h        ;执行add后,结果是:(ax)=0000H(作为无符号数,产生进位cf=1),;作为有符号数没有溢出,of=0;其它zf=1,sf=0,pf=1.我们把这些标                           ; 位按照顺序组合起来(不能确定的我们不管了):00000xxx010x0101                                     ;我们不能确定的都用X表示。没有使用的用0表示吧             pushf               ;将flag的值入栈。pop ax              ;弹栈,(ax)= 00000xxx010x0101Band al,11000101B    ;ax低8位按位与,    010x0101 and 11000101=01000101B=45Hand ah,00001000B    ;ax高8位按位与,00000xxx and 00001000=0000000B=00H
Debug中的flag 标记

试验11 书中234页

第十二章 内中断

  • CPU不再接着(刚执行完的的指令)向下执行,而是转去处理这种中断信息
  • 中断信息由CPU的内部和外部产生。
内中断的产生
  • 除法错误 执行div产生除法溢出
  • 单步执行
  • 执行into指令
  • 执行int指令
中断类型
  • 中断类型码:一个字节型数据 256中种中断信息
  • 中断信息来源:中断源
  • 除法错误:0
  • 单步执行:1
  • 执行into指令:4
  • 执行int指令:格式为 int n ,n为字节型立即数
中断向量表:中断处理程序入口地址列表
  • 中断向量表:通过中断类型码找到中断入口地址的的先决条件
  • 8086CPU中 0000:0000~003F 共1024个单元 存放中断向量表
  • 一个表存放一个地址 = 段地址+偏移地址 = 2个字大小
中断过程
  • 中断过程:通过中断类型码找到中断入口地址 设置CS:IP CPU执行中断程序
  • (中断信息中)取得中断类型
  • 标志寄存器入栈
  • 设置标志寄存器 第八位TF 和第九位IF 为0
  • CS 内容入栈
  • IP 内容入栈
  • 从内存地址为中断类型码4 和中断类型码4+2 的两个字节单元中读取中断处理程序的入口地址设置IP和CS(*4是因为每个向量地址有4个字节)
iret指令和中断处理程序

CPU随时可能执行中断程序,所以中断程序必须一直存储在内存的某段中

  • 保存用到的寄存器
  • 处理中断
  • 恢复用到的寄存器
  • 用iret指令返回

iret指令功能用汇编描述:

pop IP
pop CS
popf
除法溢出错误
mov ax,1000h
mov bh,1
div bh计算:
(al) = (ax)/((ds)*16+0)的商 = 1000h/0001H = 1000H (溢出 al范围为00H~FFH)
(ah) = (ax)/((ds)*16+0)的余数  = 0H
do0 修改 除法溢出的错误提示
  • 编写显示“overflow!”的中断程序:do0
  • 将do0送入内存0000:0200处
  • 将do0的入口地址0000:0200存储在中断向量表0号表项中

实现代码:

assume cs:code
code segmentstart:do0 安装程序 设置中断向量表mov ax,4c00hint 21hdo0:  显示字符串“overflow!”mov ax,4c00hint 21hcode endsend start
安装 do0
assume cs:code
code segmentstart:mov ax,csmov ds,ax mov si,offset do0              ;设置ds:si指向源地址mov ax,0mov es,ax                          mov di,200h                     ;设置es:di指向目的地址mov cx,offset do0end-offset do0   ;do0 部分代码的长度        ;设置cx为传输长度cld                               ;设置传输方向rep movb设置中环向量表mov ax,4c00hint 21hdo0:  显示字符串“overflow!”mov ax,4c00hint 21hcode endsend start
编写do0程序

这里存在一个问题 当code segment执行玩之后data
segment内存随时可能被释放。所以需将data实时生成。

do0代码不执行 只是装载到200H处

assume cs:codedata segmentdb "overflow!"
data endscode segmentstart:mov ax,csmov ds,ax mov si,offset do0                 ;设置ds:si指向源地址mov ax,0mov es,ax                          mov di,200h                     ;设置es:di指向目的地址mov cx,offset do0end-offset do0   ;do0 部分代码的长度        ;设置cx为传输长度cld                               ;设置传输方向rep movsb;设置中环向量表mov ax,4c00hint 21hdo0:  mov ax,data                        mov ds,axmov si,0                           ;设置ds:si指向字符串mov ax,0b800H           mov es,axmov di,12*160+36*2                ;设置es:di指向显存空间的中间位置mov cx 9                         ;设置cx字符串长度s:      mov al,[si]mov es:[di],alinc siadd di,2loop smov ax,4c00hint 21hdo0end:nopcode endsend start
改进do0
assume cs:code
code segmentstart:mov ax,csmov ds,ax mov si,offset do0              ;设置ds:si指向源地址mov ax,0mov es,ax                          mov di,200h                     ;设置es:di指向目的地址mov cx,offset do0end-offset do0   ;do0 部分代码的长度        ;设置cx为传输长度cld                               ;设置传输方向rep movsb;设置中环向量表mov ax,4c00hint 21hdo0: jmp short do0startdb "overflow!"do0start:  mov ax,cs                  mov ds,axmov si,0                           ;设置ds:si指向字符串mov ax,0b800H           mov es,axmov di,12*160+36*2                ;设置es:di指向显存空间的中间位置mov cx, 9                            ;设置cx字符串长度s:      mov al,[si]mov es:[di],alinc siadd di,2loop smov ax,4c00hint 21hdo0end:nopcode endsend start
设置中断向量

do0 入口地址0:200 0:0存偏移地址 0:200子单元存段地址.

单步中断 类似Debug的t命令单步调试
  • TF为1 则(Step Flag)
  • 去除中断类型码1 (提前置0 防止无限循环)
  • 标志寄存器入栈,TF,IF 设置为0
  • CS,IP入栈
  • (IP)=(14),(cs)= (14+2)
响应中断的特殊情况

中断后 并不会设置 ss:SP 且当执行栈操作时 不会去响应中断,此时我们应该将SS和SP连续存放

mov ax,1000h
mov ss,ax
mov sp,0
试验12 编写0号中断处理程序 书中251页

第十三章 int指令:内中断之一

格式:int n,n为中断类型码 引发中断
执行过程:

  • 去除中断类型码1 (提前置0 防止无限循环)
  • 标志寄存器入栈,TF,IF 设置为0
  • CS,IP入栈
  • (IP)=(14),(cs)= (14+2)
书中253页 编写一个中断程序

问题 编写安装中断7ch中断例程
求2*3456^2
第一步:

assume cs:codecode segmentstart :mov ax,3456int 7chadd ax,axadc dx,dxmov ax,4c00hint 21hcode endsend start

第二步:

assume cs:codecode segmentstart :mov ax,csmov ds,axmov si,offset sqrmov ax,0mov di,200hmov cx,offset sqrend-offset sqr  ;安装子程序到 es:di 也就是 0:200H处cld  ;df=0 正向传送  di si 加1rep movsb; 循环复制 (mov es:[di],byte ptr ds:[si] df=0)mov ax,0mov es,axmov word ptr es:[7ch*4],200h            ;es:[7ch*4]中断向量表 偏移地址mov word ptr es:[7ch*4+2],0           ;es:[7ch*4+2]中断向量表 段地址mov ax,4c00hint 21hsqr:   mul axiretsqrend:nopcode endsend start
```c其中iret为 恢复数 CS IP 和 flag

pop IP
pop CS
popf

######  int和iret和栈深入理解  书中256页已经变得很复杂了。可能是前面基础没打好。**先休息一下 本文共17章  且 课后试验部分未做,可谓是任重而道远,未完待续**

汇编语言(王爽)第三版-读书笔记相关推荐

  1. 汇编语言(王爽 第三版)检测点

    这本书购于2015.11.30,我大概从2016.3月开始读,历时大概三个月,我们学校开<微机原理与汇编语言>这门课,不过让人感觉很不爽,课本一开始就丢给你一堆东西,意欲让你记住这一大堆东 ...

  2. 汇编语言王爽第三版答案

    汇编语言答案(王爽) 检测点1.1 (1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为 13位. (2)1KB的存储器有 1024 个存储单元,存储单元的编号从 0 到 1023 . (3) ...

  3. 汇编语言(王爽第三版)笔记

    基础知识 1.每一种CPU(微处理器)都有自己的汇编指令集 2.汇编指令是机器指令的助记符, 与机器指令一一对应 3.地址总线宽度 => 寻址能力 数据总线宽度 => 数据传送时的数据传输 ...

  4. 汇编语言(王爽 第三版)检测点9.1 解决-a无法输入jmp dword ptr es:[1000h]

    第一个: assume cs:code,ds:data data segmentdb 0h data ends code segment start:mov ax,datamov ds,axmov b ...

  5. 汇编语言(王爽第三版)实验一

    实验一 题目预览 使用Debug,将下面的程序段写入内存,逐条执行,观察每条指令执行后的CPU中相关寄存器中内容的变化. 将下面3条指令写入从2000:0开始的内存单元中,利用这3条指令计算2的8次方 ...

  6. 汇编语言(王爽 第三版) ret retf总结 以及检测点10.1

    关键导读: ret对应的代码以及结果: assume cs:codesgstack segmentdb 16 dup(0) stack endscodesg segmentmov ax,4c00hin ...

  7. 汇编语言(王爽第三版)实验大全

    实验大全 实验1 查看CPU和内存,用机器指令和汇编指令编程 实验2 用机器指令和汇编指令编程 实验3 编程.编译.连接.跟踪 实验4 [bx]和loop的使用 实验5 编写.调试具有多个段的程序 实 ...

  8. 汇编语言(王爽第三版) 实验5

    汇编语言(王爽第三版) 实验5 由图可见: 第一问:cpu执行程序,程序返回前,ds一直未变,所以data段中的数据不变. 第二问:cpu执行程序,程序返回前,cs=1CD5,SS=1CD4,DS=1 ...

  9. 汇编语言 王爽 第四版 第三章 检测点3.2

    汇编语言 王爽 第四版 课后检测点 课后实验 持续更新~~ 检测点3.2 1 补全下面的程序,使其可以将10000H-1000FH中的8个字,逆序拷贝到20000H-2000FH中. mov ax,1 ...

  10. C++ Primer 第三版 读书笔记

    1.如果一个变量是在全局定义的,系统会保证给它提供初始化值0.如果变量是局部定义的,或是通过new表达式动态分配的,则系统不会向它提供初始值0 2.一般定义指针最好写成:" string * ...

最新文章

  1. linux终端运行pytorch,Linux虚拟机测试pytorch运行
  2. html调用相机相册案例,Ionic 相册、相机调用
  3. python代码壁纸-爬虫 抓取王者荣耀所有英雄皮肤高清壁纸+超强注释
  4. HTML5 input元素新的特性
  5. redis分布式缓存(三)
  6. mysql官网下载下来的免安装版怎么配置_Windows下的免安装版MySQL配置
  7. §4.1.2数学归纳法证明不等式第6题 (复旦大学2004年保送生考试数学试题)
  8. Unix网络编程卷1学习总结
  9. 备战数学建模10-主成分分析模型与因子分析模型
  10. android 音乐扬声器,android安插耳机状态使用扬声器外放音乐
  11. html 和 css 代码 总结
  12. linux下网口监控软件_Linux网络监控工具大点兵
  13. Oracle数据库各版本下载(迅雷复制粘贴直接下载,别进目录)
  14. Prior-Induced Information Alignment for Image Matting
  15. navicat创建用户并赋予权限
  16. MySQL数据备份命令
  17. 关于1000桶水,其中一桶有毒,猪喝毒水后会在15分钟内死去,想用一个小时找到这桶毒水,至少需要几头猪?的问题
  18. Deep Supervision:深度监督(2014)+DHM
  19. Android平台基于asmack实现XMPP协议中的PubSub机制
  20. 在线网页版鸡乐盒html源码

热门文章

  1. 赚钱、读书,提升自己
  2. 少轻狂电子图书制作教程之三:用软景HTML制造机生成网页文件
  3. 手机技巧:iOS微信 8.0.38正式版更新功能一览
  4. 第十二章 文件上传和下载
  5. 中国网上人民大学计算机在线考试,中国人民大学网络教育易考通客户端在线考试须知...
  6. 如何使用Debugging Tools for Windows (windebug)简单的使用心得
  7. 如何在WPF中载入Unity3D场景?
  8. Typora主题——无聊时候的消遣之作
  9. Java写银联支付C扫B经验分享--框架SSM
  10. c语言生小牛问题算法,数据结构算法:大牛生小牛的算法问题