《汇编语言》学习笔记

指令汇总
第二章-跳转指令
    jmp指令:(由于mov指令不能直接用于CS:IP,所以需要使用jmp指令)
        jmp 段地址:偏移地址 -> 用指令给出的段地址修改CS,用指令给出的偏移地址修改IP
        jmp 某一合法寄存器 -> 用寄存器中的值修给IP
    
    call指令:指令执行的过程:改变IP,保存IP,跳转
第三章-mov、add、sub指令
    mov指令:
    mov 寄存器,数据         mov ax,8
    mov 寄存器,寄存器       mov ax,bx
    mov 寄存器,内存单元     mov ax,[0]
    mov 内存单元,寄存器     mov [0],ax
    mov 段寄存器,寄存器     mov ds,ax
    add指令:
    add 寄存器,数据         add ax,8
    add 寄存器,寄存器       add ax,bx
    add 寄存器,内存单元     add ax,[0]
    add 内存单元,寄存器     add [0],ax
    sub指令:
    sub 寄存器,数据         sub ax,8
    sub 寄存器,寄存器       sub ax,bx
    sub 寄存器,内存单元     sub ax,[0]
    sub 内存单元,寄存器     sub [0],ax
第三章-push、pop指令
    push指令:
    push 寄存器    ;将寄存器内数据存入栈中
    push 段寄存器  ;将段寄存器内数据存入栈中
    push 内存单元  ;将内存单元内数据存入栈中
    pop指令:
    pop 寄存器      ;用一个寄存器接收出栈数据
    pop 段寄存器   ;用一个段寄存器接收出栈数据
    pop 内存单元   ;用一个内存单元接收出栈数据
第五章-inc和dec指令
    inc bx    ;bx中的内容加1,相当于:add bx,1
    dec bx   ;bx中的内容减1,相当于:sub bx,1
第五章-loop、p、g指令
    loop指令:
    codesg segment
        mov ax,2000H
        mov ds,ax           ;设置数据段起始位置
        mov cx,10H        ;设置循环次数,当cx等于0时,跳出循环;但是如果直接设置为0,则会越界

        mov al,0
        mov bx,0            ;设置偏移寄存器的起始单元地址
 
    point:  mov ds:[bx],al
        inc al
        inc bx

        loop point

        mov ax,4C00H
        int 21H
    codesg ends

    p指令:
    程序返回的 int 21 语句需要用p指令执行
    程序执行到loop指令时,可以使用p指令执行完全部循环

    g指令:
    g指令可以直接跳到代码段指定位置,并且执行完上边所有命令
第七章-and指令和or指令
    and指令:
    mov al,0110 0011B
    and al,0011 1011B
    执行后,al = 0010 0011B
    
    or指令:
    mov al,0110 0011B
    or al,0011 1011B
    执行后,al = 0111 1011B
第八章-div指令
    div是除法指令,有以下规则:
    1.除数:有8位和16位两种,存在寄存器或者内存单元中
    2.被除数:默认存放在AX或者DX和AX中:
        如果除数为8位,则被除数位16位,存放在AX中
        如果除数位16位,则被除数位32位,存放在DX和AX中,DX存放高16位,AX存放低16位
    3.结果:默认存放在AX或者DX和AX中:
        如果除数为8位,则AL存放商,AH存放余数
        如果除数位16位,则AX存放商,DX存放余数
第十章-ret和retf指令
    ret指令用栈中的数据,修改IP的内容,从而实现近转移
    相当于 pop IP
    retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移
    相当于 pop IP
               pop CS
第十章-call指令
    CPU执行call指令时,进行两步操作:
    1.将当前的IP或者CS和IP压入栈中
    2.转移
第十章-mul指令
    两个相乘的数:两个相乘的数,要么都是8位,要么都是16位。如果是8位,一个默认在AL中,另外一个放在8位reg或者内存字节单元中;如果是16位,一个默认在AX中,另外一个放在16位reg或者内存字单元中。
    结果:如果是8位乘法,结果默认放在AX中;如果是16位乘法,结果高位默认在DX中存放,低位在AX中放。

    格式如下:
    mul reg
    mul 内存单元    
第十一章-adc指令
    带进位加法指令,利用了CF位上记录的进位值
    格式:adc 操作对象1,操作对象2
    功能:操作对象1 = 操作对象1 + 操作对象2 + CF(低一位的进位)
第十一章-sbb指令
    带借位减法指令,利用了CF位上记录的借位值
    格式:sbb 操作对象1,操作对象2
    功能:操作对象1 = 操作对象1 - 操作对象2 - CF(低一位的借位)
第十一章-cmp指令
    cmp是比较指令,功能相当于减法指令,只是不保存结果,只对标志寄存器产生影响
    格式:cmp 操作对象1,操作对象2
    功能:计算 操作对象1 - 操作对象2,但是不保存结果,仅仅根据计算结果对标志寄存器进行设置

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

第一章-各个寄存器的作用
    AX    BX    CX    DX    SP    BP    SI    DI
    DS    ES    SS    CS    IP    NV  UP  EI  PL  NZ  NA  PO  NC
    
    通用寄存器:AX BX CX DX
    段寄存器:  DS ES SS CS
    偏移寄存器:BX BP SP IP SI DI
    
    组合:
        1.DS:[BX]    数据段起始位置
           DS:[SI]     数据段起始位置,SI和BX功能类似,但不能分成两个8位寄存器来使用
           DS:[DI]    数据段起始位置,SI和BX功能类似,但不能分成两个8位寄存器来使用
        2.CS:IP       代码段起始位置
        3.SS:SP      栈段段地址以及大小
        4.CX           loop指令循环的次数
        5.DS           数据从哪里来
           ES           数据到哪里去

----------------------------------------------------------------------------------------------------------          
第一章-地址总线、控制总线、数据总线
    内存的最小单位是字节(byte),一个字节由八位(bit)二进制组成
    1KB = 1024B    1MB = 1024KB    1GB = 1024MB    1TB = 1024GB
        
    CPU通过地址总线访问内存地址,CPU在地址总线上给每个模块分配了固定范围的地址,用于控制每个模块(内存、显卡、键盘、鼠标。。。)
        地址总线的带宽决定里CPU的寻址能力
    CPU通过控制总线控制器件的选择和数据的读写
        控制总线的带宽决定了CPU对系统中其他器件的控制能力
    CPU通过数据总线与内存或者其他器件进行数据的传输
        数据总线的带宽决定了CPU与其他器件数据交换时一次数据传输量
        
    因为8086CPU的地址总线带宽为20,而8086CPU的寄存器是16位结构的,所以需要使用 段地址:偏移地址 的形式来表示物理地址
        物理地址 = 段地址*16 + 偏移地址

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

第二章-CS和IP
    CS为代码段寄存器
    IP为指令指针寄存器
    8086CPU的工作过程:
        1.从CS:IP指向的内存单元中读取指令,读取的指令进入指令缓存区
        2.IP=IP+所读指令的长度,从而指向下一指令
        3.执行指令,跳转到步骤(1),重复这个过程

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

第二章-跳转指令
    jmp指令:(由于mov指令不能直接用于CS:IP,所以需要使用jmp指令)
        jmp 段地址:偏移地址 -> 用指令给出的段地址修改CS,用指令给出的偏移地址修改IP
        jmp 某一合法寄存器 -> 用寄存器中的值修给IP
    
    call指令:指令执行的过程:改变IP,保存IP,跳转

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

第二章-代码段
    将一组长度为N(N <= 64KB)、地址连续、起始位置为16的倍数的内存单元当作专门存储代码的内存空间,叫做代码段

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

第二章-debug常用命令
    R命令:查看和改变CPU寄存器的内容
        r -> 查看所有寄存器内容
        r 寄存器 + Enter -> 修改指定寄存器内内容

    D命令:查看内存中的内容
        d ->查看debug预设在地址处的内容
        d 段地址:偏移地址 -> 查看指定地址开始的 128个内存单元(字节)的内容
        d 段地址:起始偏移地址 结尾偏移地址 -> 查看指定地址范围内的内存单元的内容

    E命令:改写内存中的内容
        e 段地址:偏移地址 + Enter -> 依次修改每个内存单元的内容
        e 段地址:偏移地址 数据 “字符串” ‘字符’ -> 修改指定位置开始的连续多个内存单元内容

    U命令:将内存中的机器指令翻译成汇编指令
        u 段地址:偏移地址 -> 将指定位置开始的内存单元的内容翻译为汇编指令

    T命令:执行一条指令
        t 执行CS:IP所对应内存单元内的一条完整的指令    
        debug的t指令在执行修改寄存器SS的指令时,下一条指令也会紧接着被执行

    A命令:以汇编指令的格式在内存中写入一条机器指令
        a 以汇编指令的格式在CS:IP所对应内存中写入一条机器指令

    注:可以使用段寄存器表示内存单元的段地址

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

老师 您好,想请教您两个问题:
1.进入debug模式后,CS:IP指向的为当前CPU要执行的命令,电脑在一直运行,问什么在学习阶段IP的位置一直没有改变?
答:debug 也是一个程序,也是在内存中运行的。。
你看一下课时67 ~ 81 中间无关的跳过
首先 可以执行的程序是 exe 这个没问题吧?
课时81 说了 编译链接完成后  得到exe 会将 程序的入口地址 存放在exe 文件的一些地方
然后系统加载后 就根据 这个来 设置cs ip
debug  应该是可以模拟这个过程 也是一个加载程序 然后执行
分割线----------------------------------------
然后你指的电脑一直在运行,是操作系统在运行,因为现在的 操作系统 都是 所谓的 多任务
你想一下  现在cpu 假设1秒能执行几亿 条汇编指令 如果执行一个程序是不是很浪费?
所以 为了不造成浪费  每个 程序  都有cpu的一段时间的使用权 可能是几微妙
那么也就是说 CPU的 CS IP 其实一直是在改变的。。
然后你肯定觉得奇怪   那么我一个程序执行到一半 就去执行另外一个了??
是这样的。。 执行到一半 你不是有cs ip吗? 好 保存起来  然后 另外程序的csip 占用   好 执行一会后 再换 程序
因为每次执行都会将csip 保存起来 然后 再拿出来用   这样每个程序都可以执行下去
由于 这个  cpu 实在是 太快了。。 所以 人根本感觉不出来

2.对CS:IP所指向内存中的指令做了修改,为什么对当前电脑的执行没有产生错误,或者说我们看到的指令不是当前计算机
要执行的指令么?
答: 因为 csip 会保存   所以不会引起 错误   一个一个接着在执行,只不过每次在执行某个程序前,
cpu会将 其他程序的csip 拿出来

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

第三章-内存中字的存储
    字单元,即存放一个字型数据的单元(16位),在内存中有两个连续的内存单元(字节)组成:
        高地址内存单元存放字型数据的高位字节
        低地址内存单元存放字型数据的低位字节

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

第三章-DS和[address]
    DS用来存放要访问数据的段地址
    [address] 表示一个内存单元,address表示偏移地址

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

第三章-mov、add、sub指令
    mov指令:
    mov 寄存器,数据         mov ax,8
    mov 寄存器,寄存器       mov ax,bx
    mov 寄存器,内存单元     mov ax,[0]
    mov 内存单元,寄存器     mov [0],ax
    mov 段寄存器,寄存器     mov ds,ax
    add指令:
    add 寄存器,数据         add ax,8
    add 寄存器,寄存器       add ax,bx
    add 寄存器,内存单元     add ax,[0]
    add 内存单元,寄存器     add [0],ax
    sub指令:
    sub 寄存器,数据         sub ax,8
    sub 寄存器,寄存器       sub ax,bx
    sub 寄存器,内存单元     sub ax,[0]
    sub 内存单元,寄存器     sub [0],ax

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

第三章-数据段
    将一组长度为N(N <= 64KB)、地址连续、起始位置为16的倍数的内存单元当作专门存储数据的内存空间,叫做数据段
    将一组长度为N(N <= 64KB)、地址连续、起始位置为16的倍数的内存单元当作专门存储代码的内存空间,叫做代码段

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

第三章-栈(LIFO,后进先出)
    栈是一种具有特殊访问方式的存储空间。它的特殊性就在于,最后进入这个空间的数据最先出去。
    1.栈             箱子
    2.栈顶标记   标记了箱子中最上边的书在箱子中的位置
    3.入栈          将书放在箱子中最上边的书的位置的上方,并将栈顶标记指向该书
    4.出栈          将箱子中最上边的书取出,并将栈顶标记指向该书下边的书

   从内存角度来看:
        push ax    修改SP寄存器中的数值 SP = SP - 2
                        将ax中的字型数据放入 SS:SP所指向的内存地址中(入栈)
        pop ax     将SS:SP所指向的内存地址中的字型数据放入ax寄存器中(出栈)
                       修改SP寄存器中的数值 SP = SP + 2(数据出栈后,并没有清楚该数据,而是等下一次入栈的时候直接将该数据覆盖)
    8086CPU中,任何时刻都将段地址寄存器SS和偏移地址寄存器SP所指向的内存地址当作栈顶标记

    如何设置栈的起始位置和大小:
    SS寄存器的数值决定栈的起始位置                     
    SP = 0000 + 栈的大小(最好为16的倍数)
        SS = 2000
        SP = 10H      栈的长度为16个字节

    debug的t指令在执行修改寄存器SS的指令时,下一条指令也会紧接着被执行
    
    开始栈为空,栈顶标记指向栈最底部单元的下一个字节
    此外还要考虑栈顶超界到问题,以为8086CPU并没有判断我们对栈的操作是否会超界

    栈的作用:
    1.临时性保存数据
        比如call指令将IP保存到栈中,ret指令再将IP取回
        通用寄存器不够用,需要将寄存器内数据覆盖时,可以将数据临时保存到栈中
    2.进行数据交换
        将寄存器内数据保存到栈中,出栈时改变出栈顺序即可交换寄存器内内容

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

第三章-push、pop指令
    push指令:
    push 寄存器     ;将寄存器内数据存入栈中
    push 段寄存器  ;将段寄存器内数据存入栈中
    push 内存单元  ;将内存单元内数据存入栈中
    pop指令:
    pop 寄存器      ;用一个寄存器接收出栈数据
    pop 段寄存器   ;用一个段寄存器接收出栈数据
    pop 内存单元   ;用一个内存单元接收出栈数据

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

第三章-栈段
    将一组长度为N(N <= 64KB)、地址连续、起始位置为16的倍数的内存单元当作专门存储数据的栈空间,叫做栈段
    由段寄存器SS:偏移寄存器SP决定起始位置及大小
    将一组长度为N(N <= 64KB)、地址连续、起始位置为16的倍数的内存单元当作专门存储数据的内存空间,叫做数据段
    由段寄存器DS:内存单元[address]决定起始位置
    将一组长度为N(N <= 64KB)、地址连续、起始位置为16的倍数的内存单元当作专门存储代码的内存空间,叫做代码段
    由段寄存器CS:偏移寄存器IP决定起始位置

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

第三章-内存段的安全(代码段、数据段、栈段)
    随意地向某一段内存空间中写入内容是非常危险的,有可能会导致程序或者系统的崩溃,所以要向安全的内存空间去写入内荣
    0:200 ~ 0:2FFH是安全的内存空间
    使用操作系统分配的内存空间
        在操作系统的环境中,合法地通过操作系统取得的内存空间都是安全的,因为操作系统不会让一个程序所使用的内存空间和其他程序以及系统自己的空间产生冲突,所以在操作系统允许的情况下,程序可以取得任意容量的内存空间

    程序获取内存空间有两种:
    1.系统加载程序时为程序分配的内存空间
    2.程序在执行的过程中再向系统去申请内存

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

第四章-连接的作用
    1.当源程序很大时,可以将它分为多个源程序文件来编译,每个源程序编译成为目标文件后,再用连接程序将它们连接到一起,生成一个可执行文件
    2.程序中调用了某个库文件中的子程序,需要将这个库文件和该程序生成的目标文件连接到一起,生成一个可执行文件
    3.一个源程序编译后,得到了存有机器码的目标文件,目标文件中的有些内容还不能直接用来生成可执行文件,连接程序将这些内容处理成最终的可执行信息。所以在只有一个原程序文件,而又不需要调用某个库中的子程序的情况下,也必须用连接程序对目标文件进行处理,生成可执行文件

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

第四章-可执行文件的内容
    1.程序(从源程序中的汇编指令翻译过来的机器码)和数据(原程序中定义的数据)
    2.相关的描述信息(比如,程序有多大、要占用多大内存空间等)

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

第四章-PSP区
  从DS:0开始的256个字节,用来系统和内存通信

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

第四章-补充
    mov ax,0B800H    ;在汇编语言中,数据不能以字母开头,存入数据第一个为字母的时候,需要在前边加上0

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

第五章-[BX]
    [BX}表示一个内存单元(和[address]一样),他的偏移地址存在BX中
    inc bx    ;bx中的内容加1,相当于:add bx,1
    dec bx    ;bx中的内容减1,相当于:sub bx,1

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

第五章-loop指令
    jmp指令:    
    codesg segment
        mov al,0
        mov bx,0
        
    point:    mov ds:[bx],al    ;point:标号(内存地址)标识
        inc al
        inc bx

        jmp point         ;jmp跳到point实现循环,jmp在源程序中不能直接跳向地址  


    codesg ends

    loop指令:
    codesg segment
                mov ax,2000H
                mov ds,ax         ;设置数据段起始位置
                mov cx,10H        ;设置循环次数,当cx等于0时,跳出循环;但是如果直接设置为0,则会越界

                mov al,0
                mov bx,0          ;设置偏移寄存器的起始单元地址

    point:  mov ds:[bx],al
                inc al
                inc bx

                loop point      ;cx-1是否为0,为0的话执行下一条指令

                mov ax,4C00H
                int 21H
    codesg ends

    p指令:
    程序返回的 int 21 语句需要用p指令执行
    程序执行到loop指令时,可以使用p指令执行完全部循环

    g指令:
    g指令可以直接跳到代码段指定位置,并且执行完上边所有命令

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

第五章-补充
    DS寄存器代表数据从哪里来
    ES寄存器代表数据到哪里去
    
    为了描述简洁,以后使用“()”来表示一个寄存器或者内存单元内的内容:
    ①寄存器名;②段寄存器名;③内存单元的物理地址(一个20位数据)
        
    约定符号 idata 表示常量
    
---------------------------------------------------------------------------------------------------------

第五章-debug和汇编编译器masm对指令的不同处理
    debug:
    mov ax,[0]    ;表示将ds:0处的数据存入ax中
    汇编程序:
    mov ax,[0]    ;相当于 mov ax,0    表示将0存入ax中
        
    (1)在汇编语言中,如果用指令访问一个内存单元,则在指令中必须用“[]”来表示内存单元,如果“[]”中是常量idata的话,就要在“[]”的前面显示地给出段地址所在的段寄存器。比如:
    mov ax,ds:[0] 其中,显示地指明内存单元的段地址的“ds”,在汇编语言中成为“段前缀”
    (2)如果“[]”中是寄存器的话,间接地给出内存单元的地址,则段地址默认在ds中
    
---------------------------------------------------------------------------------------------------------
    
第六章-伪指令db和dw
    db 1    ;double byte:01H,占一个字节
    dw 1    ;double word:0001H,占两个字节,一个字

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

第六章-包含多个程序段的程序
assume cs:code,ds:data,ss:stack

a segment
        db 1,2,3,4,5,6,7,8
a ends


b segment
        db 1,2,3,4,5,6,7,8
b ends


c segment
        db 0,0,0,0,0,0,0,0
c ends


data segment

data ends


stack segment

stack ends


code segment
start:        mov ax,a
                mov ds,ax    ;数据来源    

                mov ax,c
                mov es,ax    ;数据去向

                mov bx,0H        
                mov cx,8

addnum:  push ds
                mov dl,ds:[bx]    ;将a中数据存入dl
                mov ax,b
                mov ds,ax
                add dl,ds:[bx]    ;将b中数据加入dl
                mov es:[bx],dl
                inc bx
                pop ds
                loop addnum    ;将b中数据加到c中

                mov ax,4C00H
                int 21H
code ends

end start


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

第七章-and指令和or指令
    and指令:
    mov al,0110 0011B
    and al,0011 1011B
    执行后,al = 0010 0011B
    
    or指令:
    mov al,0110 0011B
    or al,0011 1011B
    执行后,al = 0111 1011B

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

第七章-ASCII码
    在文本编辑中,我们按一下键盘“a”,屏幕就会显示“a”。这是怎样一个过程呢?
    我们在按下键盘“a”,这个按键的信息被存入计算机,计算机用ASCII码的规则对其进行编码,将其转化为61H存储在内存的制定空间中;
    文本编辑软件从内存中取出61H,将其送到显卡的显存中;
    工作在文本模式下的显卡,用ASCII码的规则解释显存中的内容,61H被当做字符“a”,显卡驱动器,将字符“a”的图像画在屏幕上。

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

第七章-以字符形式给出的数据
    在定义数据段或这栈段的时候可以这样定义:
    db 'abc 123'

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

第七章-SI和DI
    si和di是8086cpu中和bx功能相近的寄存器,si和di不能够分成两个8位寄存器来使用。
    DS:[BX]    数据段起始位置
    DS:[SI]    数据段起始位置,SI和BX功能类似,但不能分成两个8位寄存器来使用
    DS:[DI]    数据段起始位置,SI和BX功能类似,但不能分成两个8位寄存器来使用

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

第七章-不同的寻址方式的灵活运用
    1.[idata]用一个常量来表示地址,可用于直接定位一个内存单元,直接寻址;
    2.[bx]用于一个变量来表示内存地址,可用于间接定位一个内存单元,寄存器间接寻址;
    3.[bx+idata]用于一个变量和常量表示地址,可在一个起始地址的基础上用变量间接定位一个内存单元,寄存器相对寻址;
    4.[bx+si]用两个变量来表示地址,基址变址寻址;
    5.[bx+si+idata]用两个变量和一个常量表示地址,相对基址变址寻址。

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

第七章-二重循环
    二重循环,使用栈来暂时保存外层循环的cx,内层循环结束后,再恢复外层循环的cx

assume ss:stack,ds:data,cs:code

stack segment
        dw 0,0,0,0,0,0,0,0
stack ends


data segment
        db '1. display      '
        db '2. brows        '
        db '3. replace      '
        db '4. modify       '
data ends


code segment
start:        mov ax,stack
                mov ss,ax     ;栈段
        
                mov ax,data
                mov ds,ax    ;数据段

                mov bx,0
                mov cx,4

setout:        push cx
                mov cx,4
                mov si,0

setin:        mov al,ds:[bx+si+3]    ;针对内循环,将每一个单词的前四个字母变为大写
                and al,11011111B
                mov ds:[bx+si+3],al
                inc si
                loop setin

                add bx,10H
                pop cx
                loop setout        ;针对外循环,遍历四个单词,执行内循环

                mov ax,4C00H
                int 21H
code ends


end start

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

第八章-通过byte ptr和word ptr判断数据长度
    mov ds:[0],1                      ;不能判断 1 的长度
    mov byte ptr ds:[0],1        ;1 的长度为8位
    add word ptr ds:[0],255    ;255 的长度位16位

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

第八章-bx、si、di和bp
    1.在8086CPU中,只有这四个寄存器可以在“[....]”中来进行内存单元的寻址
    2.在[....]中,这四个寄存器可以单个出现,或只能以四种组合出现:
    bx和si、bx和di、bp和si、bp和di
    3.只要在[....]中使用寄存器bp,而指令中没有显性的给出段地址,段地址就默认为在ss中

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

第八章-机器指令处理的数据的位置
    1.立即数---执行前在CPU的指令缓存器中
    2.寄存器---指令要处理的数据在寄存器中,在汇编指令中给出相应的寄存器名
    3.段地址(SA)和偏移地址(EA)---指令要处理的数据在内存中

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

第八章-寻址方式
    1.[idata]用一个常量来表示地址,可用于直接定位一个内存单元,直接寻址;
    2.[bx]用于一个变量来表示内存地址,可用于间接定位一个内存单元,寄存器间接寻址;
    3.[bx+idata]用于一个变量和常量表示地址,可在一个起始地址的基础上用变量间接定位一个内存单元,寄存器相对寻址;
    4.[bx+si]用两个变量来表示地址,基址变址寻址;
    5.[bx+si+idata]用两个变量和一个常量表示地址,相对基址变址寻址。

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

第八章-div指令
    div是除法指令,有以下规则:
    1.除数:有8位和16位两种,存在寄存器或者内存单元中
    2.被除数:默认存放在AX或者DX和AX中:
        如果除数为8位,则被除数位16位,存放在AX中
        如果除数位16位,则被除数位32位,存放在DX和AX中,DX存放高16位,AX存放低16位
    3.结果:默认存放在AX或者DX和AX中:
        如果除数为8位,则AL存放商,AH存放余数
        如果除数位16位,则AX存放商,DX存放余数

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

第八章-伪指令dd
    db 1    ;double byte:01H,占一个字节
    dw 1    ;double word:0001H,占两个字节,一个字
    dd 1    ;double double word:0000 0001H,占四个字节,两个字

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

第八章-伪指令dup
    dup需要和db、dw、dd配合使用:
    db 3 dup (0)                  ;定义了3个字节0,0,0
    db 3 dup (0,1,2)             ;定义了9个字节:0,1,2,0,1,2,0,1,2
    db 3 dup ('abc','ABC')    ;定义了18个字节:‘abcABCabcABCabcABC’
    dw、dd同理

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

第九章-转移指令
    可以修改IP或者同时修改CS和IP的指令统称为转移指令
    无条件转移指令(如:jmp)
    条件转移指令
    循环指令(如:loop)
    过程
    中断

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

第九章-offset指令
    1.伪指令,用于取得标号的偏移地址
        start:mov ax,offset start    ;相当于 mov ax,0
    
    2.段地址的引用
        data segment
        db 1,1
    data ends

    code segment
        staer:mov ds,data    ;将data段的段地址存入ds中
    code ends

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

第九章-jmp指令原理
start:            jmp short s        ;0000:0003 EB03      
                    add ax,1             ;0000:0005 050100
s:                  inc ax                 ;0000:0008 40

    CPU在执行jmp指令的时候并不需要转移的目的地址,而是需要转移的位移,即:
    8位位移=标号处的地址-jmp指令后的第一个字节的地址(0008-0005)

    jmp short 标号---段内段转移,8位位移地址
    jmp near ptr 标号---段内近转移,16位位移地址
    jmp far ptr 标号---段间转移、远转移,包含转移的目标地址

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

第九章-jcxz指令
    jcxz-jmp cx寄存器 zero,当cx寄存器等于0的时候,进行跳转
    jcxz是条件转移指令,所有的条件转移指令都是短转移
    8位位移=标号处的地址-jcxz指令后的第一个字节的地址
    8位位移的范围位-128~127,用补码表示
    8位位移由编译程序在编译的时候算出

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

第九章-loop指令
    loop是循环指令,所有的循环指令都是短转移
    8位位移=标号处的地址-loop指令后的第一个字节的地址
    8位位移的范围位-128~127,用补码表示
    8位位移由编译程序在编译的时候算出

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

第九章-转移地址的三种位置
    转移的目的地址在指令中的jmp指令
start:        jmp far ptr s        ;第一种
                  db 256 dup (0)
s:                add ax,1

                  jmp 0000:FFFFH    ;第二种

    转移地址在寄存器中的jmp指令
        mov ax,FFFFH
        jmp ax

    转移地址在内存中的jmp指令
    1.jmp word ptr 内存单元地址(段内转移)
        从内存单元处开始存放着的一个字,是转移的目的偏移地址
    2.jmp dword ptr 内存单元地址(段间转移)
        从内存单元处开始存放着的两个字,高地址出的字是转移的目的段地址,低地址处是转移的目的偏移地址

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

第十章-ret和retf指令
    ret指令用栈中的数据,修改IP的内容,从而实现近转移
    相当于 pop IP
    retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移
    相当于 pop IP
               pop CS

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

第十章-call指令
    CPU执行call指令时,进行两步操作:
    1.将当前的IP或者CS和IP压入栈中
    2.转移

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

第十章-call指令用法
    1.根据位移进行转移的call指令
    call 标号
    相当于:
        push IP
         jmp near ptr 标号
    2.转移的目的地址在指令中的call指令
    call far ptr 标号
    相当于:
        push CS    
        push IP
        jmp far ptr 标号
    3.转移地址在寄存器中的call指令
    call 16位reg
    相当于:
        push IP
        jmp 16位reg
    4.转移地址在内存中的call指令
    1)call word ptr 内存单元地址
    相当于:
        push IP
        jmp word ptr 内存单元地址
    2)call dword ptr 内存单元地址
    相当于:
        push CS
        push IP
        jmp dword ptr 内存单元地址

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

第十章-mul指令
    两个相乘的数:两个相乘的数,要么都是8位,要么都是16位。如果是8位,一个默认在AL中,另外一个放在8位reg或者内存字节单元中;如果是16位,一个默认在AX中,另外一个放在16位reg或者内存字单元中。
    结果:如果是8位乘法,结果默认放在AX中;如果是16位乘法,结果高位默认在DX中存放,低位在AX中放。

    格式如下:
    mul reg
    mul 内存单元

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

第十一章-标志寄存器
                                    真                            假
 标志                            值为1                        值为0
 OF(Overflow Flag)      OV                            NV                        判断运算结果是否超过了8位或者16位有符号数的表示范围
 
 SF(Sign Flag)              NG(Negative)           PL(Positive)           判断结果是否是负数
 
 ZF(Zero Flag)              ZR(Zero)                   NZ(Not Zero)        判断两个数是否相等
 
 PF(Parity Flag)            PE(Parity EVEN)        PO(Parity ODD)     判断二进制中1的个数是否是偶数
 
 CF(Carry Flag)            CY(Carry Yes)            NC(Not Carry)        判断是否有进位        
 
 DF                              DN                            UP
 
    标志寄存器和运算指令相关,和移动指令无关

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

第十一章-adc指令
    带进位加法指令,利用了CF位上记录的进位值
    格式:adc 操作对象1,操作对象2
    功能:操作对象1 = 操作对象1 + 操作对象2 + CF(低一位的进位)

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

第十一章-sbb指令
    带借位减法指令,利用了CF位上记录的借位值
    格式:sbb 操作对象1,操作对象2
    功能:操作对象1 = 操作对象1 - 操作对象2 - CF(低一位的借位)

---------------------------------------------------------------------------------------------------------
第十一章-cmp指令
    cmp是比较指令,功能相当于减法指令,只是不保存结果,只对标志寄存器产生影响
    格式:cmp 操作对象1,操作对象2
    功能:计算 操作对象1 - 操作对象2,但是不保存结果,仅仅根据计算结果对标志寄存器进行设置

---------------------------------------------------------------------------------------------------------
补充-32位寄存器
    寄存器        主要用途                                                                    存储范围
    EAX           累加器                                                                           32位
    ECX           计次                                                                               32位
    EDX           I/O指针                                                                         32位
    EBX           DS段的数据指针                                                             32位
    ESP           堆栈指针                                                                         32位
    EBP           SS段的数据指针                                                               32位
    ESI            字符串操作的源指针:SS段的数据指针                             32位
    EDI           字符串操作的数据指针;ES段的数据指针                          32位

      一个由C/C++编译的程序占用的内存分为以下几个部分 :
  1、栈区(stack)由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。  
  2、堆区(heap)一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。  
  3、全局区(静态区)(static)全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。  
  4、文字常量区,常量字符串就是放在这里的。程序结束后由系统释放。
  5、程序代码区,存放函数体的二进制代码。















































































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值