汇编语言学习小结

学习汇编语言也有一个学期了,在这里就把之前学到的一些东西梳理一遍,也当做复习了

1、输出字符串

调用9号功能,同时要mov dx,string,把要输出的放到dx中,才能输出

 1 data segment
 2     string1 db 0dh,0ah,'hello world','$'
 3 data ends
 4 
 5 code segment
 6 main proc far
 7     assume cs:code,ds:data
 8     mov ax,data
 9     mov ds,ax
10     lea dx,string1
11     mov ah,09h
12     int 21h
13     mov ah,4ch;
14     int 21h
15     ret
16 main endp
17 code ends
18     end main

其中:

mov ah,4ch

表示结束程序,返回操作系统

Immediate mode illegal

表示立即数模式错误,找个寄存器过渡一下就好

2、输出数字

输出数字这里还分为两种情况,一种是0-9的,另一种是大于9的

大于9的话要除以10,其十位数字在al中,余数(即个位数字)在ah中

 1 data segment
 2     num db 12;需要显示的10进制数
 3 data ends
 4 code segment
 5     assume cs:code,ds:data
 6 main proc far
 7 start:
 8     mov ax,data
 9     mov ds,ax
10     mov al,num
11     mov ah,0
12     div 10 ;12除以10
13     mov dl,al ;显示十位
14     mov ah,02h
15     int 21h
16     mov dl,ah ;显示个位
17     mov ah,02h
18     int 21h
19     mov ah,4ch ;结束程序
20     int 21h
21     ret
22 main endp
23 code ends
24     end start

3、输出空格

空格的ASCII码是0ah或者0dh

code segment
    assume cs:code
main proc far
    mov al,0ah
    mov dl,al
    mov ah,02h
    int 21h
    mov ah,4ch
    int 21h
    ret
main endp
code ends
    end main

这个在定义字符串的时候也有体现

string1 dw 'helloworld',0ah,0dh,'$'

4、8086寄存器组

寄存器可以分为程序可见的寄存器程序不可见的寄存器两大类。

程序可见的寄存器可以分为以下三类:

  • 通用寄存器
  • 专用寄存器
  • 段寄存器

通用寄存器

数据寄存器

AX、BX、CX、DX可称为数据寄存器,用来暂时存放计算过程中所用到的操作数。它们是16位,但也可以按字节访问,比如AH(高位字节)和AL(低位字节)。

AX

(accumulator),作为累加器用,所以是算术运算的主要寄存器。

BX

(base),在计算存储器地址时,常用作基址寄存器。

CX

(count),常用来保存计数值,如在移位指令、循环指令和串处理指令中用作隐含的计数器。

DX

(data),一般在作双字长运算时把DX和AX组合在一起存放一个双字长数,DX用来存放高位字。

指针寄存器

可以存放操作数,但只能以字为单位使用。

SP

(stack pointer),堆栈指针寄存器。

BP

(base pointer),基址指针寄存器。可以和堆栈段寄存器SS联用来确定堆栈段中的某一存储单元的地址。

SI

(source index),源变址寄存器,一般与数据段寄存器DS联用,用来确定数据段中某一存储单元的地址。

DI

(destination index),目的变址寄存器,一般与数据段寄存器DS联用,用来确定数据段中某一存储单元的地址。

※SI和DI有自动增量和自动减量的功能。

串处理指令中,SI和DI作为隐含的源变址和目的变址寄存器,此时SI和DS联用,DI和附加段寄存器ES联用,分别达到在数据段和附加段中寻址的目的。

专用寄存器

IP

(instruction pointer),指令指针寄存器,它用来存放代码段中的偏移地址。

在程序运行的过程中,它始终指向下一条指令的首地址,它与段寄存器CS联用确定下一条指令的物理地址。

SP

(stack pointer),堆栈指针寄存器,存放栈顶的偏移地址与堆栈段寄存器SS联用来确定堆栈段中栈顶的地址。

FLAGS

标志寄存器,又称为程序状态寄存器(program status word,PSW)。

条件标志

  • 溢出标志

    (overflow flag,OF),运算溢出时为1,否则为0。

  • 符号标志

    (sign flag,SF),运算结果为负时为1,否则为0。

  • 零标志

    (zero flag,ZF),运算结果为0时为1,否则为0。

  • 进位标志

    (carry flag,CF),记录运算时从最高有效位产生的进位值。有进位时为1,否则为0。

  • 辅助进位标志

    (auxiliary carry flag,AF),..…

  • 奇偶标志

    (parity flag,PF),结果操作数中1的个数为偶数时为1否则置0

控制标志

方向标志(direction flag),在串处理指令中控制处理信息的方向用。

DF为1时,高地址到低地址,即倒着来。

DF为0时,低地址到高地址,即正着来。

系统标志

  • 陷阱标志

    (trap flag,TF),用于调试时的单步方式操作。

    TF为1时,产生陷阱;否则不产生。

  • 中断标志

    (interrupt flag,IF),当其为1时,允许CPU响应中断;否则不允许。

段寄存器

段寄存器也是一种专用寄存器,专用于存储器寻址,用来直接或间接存放段地址

  • 代码段

    (code segment,CS),存放当前正在运行的程序。

  • 数据段

    (data segment,DS),存放当前运行程序所用的数据。

    如果程序使用了串处理指令,则其源操作数也存放在数据段里。

  • 堆栈段

    (stack segment,SS)

  • 附加段

    (extra segment,ES),附加的数据段,作为辅助的数据区,也是串处理指令的目的操作数存放区。

转载自@CXY https://chouxianyu.github.io/2019/05/31/80x86%E5%AF%84%E5%AD%98%E5%99%A8%E7%BB%84/#more

5、与数据有关的寻址方式

与数据有关的寻址方式

立即寻址方式

操作数直接存放在指令中,这样的操作数称为立即数

=操作数=立即数
  • mov ax,3

注意

  • 立即寻址方式只能用于源操作数字段。
  • 源操作数长度应与目的操作数长度一致。

寄存器寻址方式

操作数存放在寄存器中,指令指定寄存器号

  • mov ax,bx
=操作数=指定寄存器中的内容

以上两种寻址方式都不涉及存储器。


以下各种寻址方式的操作数都存放在存储区中。

在80x86中,把操作数的偏移地址称为有效地址EA(Effective Address)

以下各种寻址方式通过不同途径求得操作数的有效地址,进而获得操作数。

=+×+有效地址=基址+变址×比例因子+位移量

有效地址可以有以下四种成分组成:

  • 位移量

    (displacement),是存放在指令中的数字,但它不是立即数,而是一个地址。

  • 基址

    (base),是存放在基址寄存器中的内容,通常用来指向数据段中数组或字符串的首地址。

  • 变址

    (index),是存放在变址寄存器中的内容,通常用来访问数组中的某个元素或字符串中的某个字符。

  • 比例因子

    (scale factor),其值可为1,2,4,8。(386及后继机型才有比例因子)\

<center>表1 16/位寻址时有效地址三种成分的组成</center>
成分 16位寻址
位移量 0,8,16位
基址寄存器 BX,BP
变址寄存器 SI,DI
表2 默认段选择规则
访存类型 所用段及段寄存器 缺省规则
指令 代码段 CS 用于取指令
堆栈 堆栈段 SS 进出栈,ESP、BP或ESP作为基址寄存器
局部数据 数据段 DS 除堆栈和串指令的目的串之外
目的串 附加数据段 ES 串处理指令的目的串

禁止使用段跨越前缀的三种情况

  • 串处理指令的目的串必须使用ES段
  • PUSH和POP指令的源必须使用SS段
  • 指令必须存放在CS段

直接寻址方式

=有效地址=位移量
  • mov ax,[0]

位移量可以用符号地址(变量)表示。

  • mov ax,table
  • mov ax,[table]

默认段寄存器为DS。

该寻址方式适用于处理单个变量。

寄存器间接寻址方式

=有效地址=基址寄存器或变址寄存器的内容
  • mov ax,[bp]
  • mov ax,[bx]

有效地址就在某个寄存器(BX,BP,SI,DI)中。(不允许使用AX,CX,DX)

BP的默认段寄存器为SS,其他寄存器的默认段为DS。

寄存器相对寻址方式

又称直接变址寻址方式。

=+有效地址=一个基址寄存器或变址寄存器的内容+位移量

默认段情况与寄存器间接寻址方式相同。

  • mov ax,count[si]
  • mov ax,[count+si]

基址变址寻址方式

=+有效地址=一个基址寄存器的内容+一个变址寄存器的内容

默认段情况参看表1和表2。

  • mov ax,[bx][di]
  • mov ax,[bp][si]
  • mov ax,[bx+di]

相对基址变址寻址方式

=++有效地址=一个基址寄存器的内容+一个变址寄存器的内容+位移量
  • mov ax,mask[bx][si]

与转移地址有关的寻址方式

这种寻址方式用来确定转移指令与CALL指令的转向地址。

段内直接寻址

有效地址=(IP)+位移量

近转移

位移量为16bit,如jmp near ptr next

短转移

位移量为8bit,如jmp short next,看看其他寻址会与转移地址有关的寻址方式会发现只有short没有ptr

段内间接寻址

有效地址=寄存器或存储单元内容。

该内容可以用除立即寻址方式以外的与数据有关的所有寻址方式。

  • jmp bx

  • jmp word ptr[bp+table]

    word ptr说明是一个字,所以是段内转移。

段间直接寻址

指令中直接提供了转向段地址偏移地址

  • jmp far ptr next

段间间接寻址

取存储器中的两个相继字取代IP和CS中的原始内容,以达到段间转移的目的。

存储单元地址除立即寻址方式和寄存器方式外均可。

  • jmp dowrd ptr[table+bx]

    dword说明是双字,所以是段间转移。

转载自@CXY https://chouxianyu.github.io/2019/05/31/80x86%E5%AF%BB%E5%9D%80%E6%96%B9%E5%BC%8F/#more

猜你喜欢

转载自www.cnblogs.com/TheSilverMoon/p/10957476.html