自学完王爽老师的汇编语言,对一些关键知识点进行梳理。

目录

第一章 基础知识

第二章 寄存器

第三章 寄存器(内存访问)

第4章 第一个程序

第5章 [BX]和loop指令

第6章 包含多个段的程序

第7章 更灵活的定位内存地址的方法

第8章 数据处理的两个基本问题

第9章 转移指令的原理

第10章 CALL和RET指令

第11章 标志寄存器

第12章 内中断

第13章 int指令

第14章 端口

第15章 外中断

第16章 直接定址表

第17章 使用BIOS进行键盘输入和磁盘读写

附注:

1.Intel系列微处理器的3中工作模式

2.补码

3.汇编编译器(masm.exe)对jmp的相关处理

4.用栈传递参数


第一章 基础知识

汇编语言→编译器→机器语言
汇编语言由汇编指令、伪指令和其他符号3类指令组成,汇编指令有对应的机器码,其他两类没有,由编译器识别执行
每一种CPU都有自己的汇编指令集
CPU对外部设备不能直接控制,如显示器、音响等,直接控制的是扩展卡槽上的接口卡,如显卡、声卡、网卡等。内存条的接口卡集成在主板芯片或者CPU内部。
各类存储器芯片分为RAM和ROM。RAM包括主板和一些接口卡上的RAM,主板上的RAM并非内存条,而是一种CMOS,记录一些关键数据,显卡上的RAM即显存;ROM包括主板和接口卡上的ROM,一般装有BIOS。
内存地址空间是将所有的物理存储器看成一个假象的逻辑存储器,每一个物理存储器占有这个假想存储器的一段地址空间,这个假想的逻辑存储器的所有地址空间就构成了内存地址空间。8086pc机主要包括主存储器地址空间、显存地址空间和各类rom地址空间,主存储器地址空间主要由主板上的ram和内存条的ram构成。
上述内容可自行参考计组更新,有些已经不适用。

第二章 寄存器

8086pc机有14个16位寄存器,AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW
通用寄存器AX、BX、CX、DX,可以分为2个8位寄存器使用
1个字由2个字节组成,书写习惯先写高八位,内存先储存低八位在低地址单元
数据传输和运算时,指令的两个操作对象位数应该一致
16位CPU的结构特性:1.运算器一次最多处理16位数据 2.寄存器最大宽度16位 3.寄存器和运算器通路16位
8086cpu有20位地址总线,物理地址=段地址SA*16+偏移地址EA,偏移地址有16位,所以一个段的长度最大为64KB
物理地址21F60h=2000h:1F60h=2100h:0F60h=...有多种表示
段寄存器CS、DS、SS、ES
CS为代码段寄存器 IP为指令指针寄存器,CS:IP指向的内容被当做指令执行
8086cpu工作过程:1.从CS:IP处读取指令进入指令缓冲器 2.IP=IP+所读取的指令长度 3.执行指令,转到1,重复这个过程

Debug的使用
Debug是windows提供的实模式程序调试工具,默认所有数据为16进制
功能:
r 查看寄存器内容
r +寄存器 修改寄存器内容
d+段地址:偏移地址 查看从指定地址开始的128个内存单元的内容
d+段地址:起始偏移地址 结尾偏移地址 查看指定范围的内存单元内容
e+起始地址 数据 数据...修改内存单元内容
u+起始地址 将起始地址开始的内存单元的机器码翻译为汇编指令
t 执行一条或多条指令,执行多条情况例如修改栈顶地址时会接连改变ss和sp
p 单步执行时int 21使用p命令,遇到loop指令使用p可以执行完循环
g+偏移地址 程序执行到cs:偏移地址处(该处未执行)
a+起始地址 以汇编指令的形式向内存中写入机器指令
q 退出debug

第三章 寄存器(内存访问)

DS段寄存器一般用来存储段地址
mov 目的操作数,源操作数

    
注:1.cs段寄存器通过转移指令修改 2.立即数可以和内存单元间操作但需要指明内存大小 如:mov word ptr bx,idata 
栈:LIFO(后进先出)
8086cpu入栈和出栈都是以字为单元进行
push和pop后跟 16位寄存器或者内存地址(字地址)
push ax:1.sp=sp-2,ss:sp指向新的栈顶 2.ax的内容送进ss:sp
pop ax:1.ss:sp的内容送进ax 2.sp=sp+2,ss:sp指向新的栈顶
8086CPU并不知道栈空间多大,有可能栈顶超界
初始设置sp=0,一直压栈,当再次sp=0,栈顶将环绕

第4章 第一个程序

汇编源程序→编译连接→可执行文件
可执行文件包含:1.程序和数据 2.描述信息(如:程序多大,占用多大内存)
操作系统依照可执行文件中的描述信息,将可执行文件中的机器码和数据加载进内存,并进行相关初始化操作(如设置cs:ip指向第一条要执行的指令),然后由cpu执行程序
汇编源程序有两种指令:1.汇编指令,有对应的机器码,由cpu执行 2.伪指令,由编译器执行
段名 segment
...
段名 ends
定义一个段
end 编译器结束对源程序的编译
assume 编译器将程序中的一个段与特定寄存器联系起来 assume cs:代码段名 为汇编源程序开头所必须
标号指代一个地址,这个地址取决于程序分配在内存的起始地址
mov ax,4c00h    int 21h  程序返回:将CPU的控制权交给使它得以运行的程序

编辑:方式多样,保存为纯文本文件即可
编译:使用微软的masm汇编编译器,运行masm.exe,输入汇编源程序文件名,输入目标文件名 (输入列表文件名 输入交叉引用文件名),()内可以省略,最多可以得到3个输出文件目标文件(.obj)列表文件(.lst)交叉引用文件(.crf),后两个是中间结果
连接:运行link.exe,输入要被连接的目标文件名,输入可执行文件名(输入映像文件名),输入要使用的库文件名,()内可以省略,得到可执行文件(.exe)
连接的作用:1.源程序很大时可以将它分为多个源程序 文件编译,再连接到一起生成一个可执行文件 2.当调用到某个库文件的子程序时,需将库文件连接到一起生成一个可执行文件 3.目标程序中有些内容无法直接用来生成可执行文件,连接程序把这些内容处理为最终的可执行信息。
简化的编译连接:masm +源程序路径文件名+; link+目标文件路径文件名+;
编程→1.asm→编译(masm)→1.obj→连接(link)→1.exe→加载(command)→内存中的程序→运行(CPU)
跟踪:使用debug加载可执行文件进内存后,cx存放程序长度,ds存放这段内存区的段地址(PSP头),这段内存的前256个字节称为程序段前缀(PSP,操作系统用来与被加载程序通信),ss=ds+0fh,cs存放程序开始的段地址,在程序开头没有其他段的情况下cs=ds+10h(ds*16+0+256=ds*16+16*16+0=(ds+16)*16+0)

第5章 [BX]和loop指令

[BX]表示一个内存单元,偏移地址在bx,段地址默认在ds
完整描述一个内存单元:1.内存单元地址2.内存单元的长度类型
inc bx,bx的内容加1
loop 标号 执行loop指令时:1.(cx)=(cx)-1 2.判断cx里的值,不为0转至标号处执行,为0向下执行

循环框架:
mov cx,循环次数
s:
循环执行的程序段
loop s

ds:cs:es:ss:用于显式指明内存单元的段地址,称为段前缀
dos方式(实模式)下,dos没有能力对硬件系统进行全面、严格地管理,可以直接用汇编语言去操作硬件,但在windows、unix这些运行与CPU保护模式下的操作系统,不理会操作系统用汇编语言去操作真实的硬件是根本不可能的。
dos方式下,0:200-0:2ff这段空间是安全的,没有系统或者其他程序的数据或者代码。

第6章 包含多个段的程序

dw 0123h,0456h...定义字型数据
end 标号 指示程序结束和程序的入口在标号处(如果不指明程序入口,将从加载进内存的第一个单元开始执行)
段名 segment  段名 ends 定义一个段
对于一个段中的数据站N个字节,程序加载后,这段实际占有的空间为⌈该段定义的字节数/16⌉*16 个字节
关于assume的作用见这位博主的文章汇编语言——assume的作用

第7章 更灵活的定位内存地址的方法

and 指令:逻辑与指令,按位进行与运算,可以将操作对象的相应位设为0,其他位不变
or 指令:逻辑或指令,按位进行或运算,可以将操作对象的相应位设为1,其他位不变
工作在文本模式的显卡,用ASCII码的规则解释显存中的数据
db 'unIX' 定义字符型数据,会存储成相应的ASCII码
小写字母的ASCII码比大写字母大20h,在二进制的显示下,二者的区别仅在第5位是0还是1

si和di是8086CPU和bx功能相近的寄存器,但是不能分为两个8位存储器来使用
[bp]的默认段寄存器在ss中
mov ax,[bx+bp]    mov ax,[si+di] 为错误用法
利用栈存储外层循环数,来实现双重循环

第8章 数据处理的两个基本问题

立即数在执行指令时直接装入指令缓冲器中
指令处理的数据有3个位置:CPU内部、内存、端口
指令要处理的数据的长度通过以下方式表示:1.通过寄存器指明字还是字节,ax、al 2.用操作符X ptr指明内存单元的长度,X可为word或byte,在没有寄存器参与的内存单元访问中,表名内存单元的长度是必须的 3.有些指令默认访问的是字单元还是字节单元,比如栈操作push和pop,默认字操作
用bx定位整个结构体,idata定位结构体中的某个数据项,si定位数组项的每个元素
div +寄存器或者内存单元 除法指令 除数有8位和16位两种,在一个寄存器或者内存单元中;若除数为8位,被除数则为16位,默认放在ax,若除数为16位,被除数则为32位,默认dx存放高16位,ax存放低16位;若除数为8位,则al存放结果的商,ah存放结果的余数,若除数为16位,则ax存储结果的商,dx存储余数。
dd 伪指令定义双字型数据 
dup 伪指令与db、dw、dd配合使用,用来进行数据的重复
db 3 dup (0)定义3个字节,值均为0;db 3 dup (0,1,2)定义了9个字节,分别是0、1、2、0、1、2、0、1、2

第9章 转移指令的原理

可以修改IP或者同时修改CS和IP的指令统称为转移指令

8086pc转移指令分类:无条件转移、条件转移、循环指令、过程、中断

dec 自减指令
jmp 2000:0100 在debug中使用,在源程序中使用,编译会出错
80*25彩色字符模式显示缓冲区,一个字符占两个字节,低位字节存储字符的ASCII码,高位字节存储字符属性

第10章 CALL和RET指令

call指令无法实现短转移,1. 将当前的IP或CS和IP压入栈中 2.转移

子程序标准框架:
子程序开始:子程序中使用的寄存器入栈
                      子程序内容
                      子程序中使用的寄存器出栈
                      返回(ret,retf)

第11章 标志寄存器

8086PC的标志寄存器是按位起作用的,除下面标注的位,其余位没有意义

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
OF DF IF TF SF ZF AF PF CF

注意8086中逻辑或运算指令如add、sub、mul、div、inc、or、and等影响flag寄存器,传送指令如mov、push、pop等不影响flag寄存器,inc、loop不影响CF位
在进行算术运算时,既可以把两个数看成有符号数,也可以看成无符号数,得到的结果是同一个,从有无符号两个角度可以解读同一个结果的不同意义。

adc 带进位加法指令,利用了CF位记录的进位值,指令格式:adc 对象1,对象2,对象1=对象1+对象2+CF
adc可以用来进行大数加法,如:两个大于16位的数相加,add 两个数的低16位,adc两个数的其他位
sbb 带借位减法指令,利用了CF位记录的借位值,指令格式:sbb 对象1,对象2,对象1=对象1-对象2-CF
sbb可以用来进行大数减法,如:两个大于16位的数相减,sub 两个数的低16位,sbb两个数的其他位

cmp比较指令 cmp 对象1,对象2 功能:计算对象1-对象2但并不保存结果,仅仅根据结果对flag寄存器进行设置,逻辑含义是比较对象1和对象2的大小。cmp指令和add、sub指令一样也包含两种含义:进行无符号数比较和有符号数比较。


无符号数比较依据cmp设置flag寄存器的zf,cf位;有符号数比较依据cmp设置flag寄存器的sf,of,zf位
串传送需要确定:传送的原始位置,传送的目的位置,传送的长度(cx寄存器),传送的方向(df位)
pushf 将flag寄存器的值压栈  popf 从栈中弹出数据送入flag寄存器
debug中对已知的标志位的表示:

debug中对已知的标志位的表示
标志 值为1 值为0
OF OV NV
SF NG PL
ZF ZR NZ
PF PE PO
CF CY NC
DF DN UP

第12章 内中断

中断信息可以来自CPU内部和外部,中断信息必须包含识别来源的编码(中断类型码),它是一个字节型数据,可以表示256种中断信息的来源。


CPU收到中断信息后,需要对中断信息处理,用来处理中断信息的程序称为中断处理程序,一般需要对不同中断信息编写不同的处理程序。CPU用中断类型码通过中断向量表找到响应的中断处理程序入口地址。中断向量就是中断处理程序的入口地址。对于8086pc机中断向量表指定放在内存0000:0000到0000:03FF的1024个单元,一个表项占两个字,高位地址放段地址,低位地址放偏移地址。
存储N号中断源对应的中断处理程序入口的偏移地址的内存单元的地址为4N,段地址的内存单元的地址为4N+2.

一般:安装中断处理程序、设置中断向量表、编写中断处理程序
Debug提供了单步中断的中断处理程序,功能为显示所有寄存器的内容后等待输入命令。然后在抵用t命令执行指令时,Debug将TF设置为1,使得CPU工作于单步中断方式下,则在CPU执行完这条指令后就引发单步中断。但是在执行中断处理程序的第一条指令后,TF仍然等于1,这样又会引发中断...陷入无限循环,故在进入中断处理程序前设置TF=0

响应中断的特殊情况:CPU在执行完当前指令后,即便是发生中断,也不会响应。如:在执行完向ss寄存器传送数据的指令后,即使发生中断,也不会响应。因为ss:sp指向栈顶,对他们的设置应该连续完成,若在执行完设置ss的指令后,CPU响应中断,引发中断过程,要在栈中压入flag、CS和IP的值,但是ss改变,sp未改变,将引发错误。所以cpu在执行完设置ss的指令后,不响应中断。所以我们应该利用这个特性,连续依次设置ss和sp。所以之前说的t单步执行引发的单步中断不会再设置ss后响应。

第13章 int指令

CPU执行int n指令,相当于引发一个n号中断的中断过程。
中断处理程序有系统提供的,也可以自己写,安装到指定位置。

可以使用int指令直接调用BIOS和DOS提供的中断例程。和硬件设备相关的DOS中断例程中,一般都调用了BIOS的中断例程。

一般一个供程序员调用的中断例程中往往包括多个子程序,中断例程内部用传递进来的参数来决定哪一个子程序。BIOS和DOS提供的中断例程,都用ah来传递内部子程序的编号。
int 10h是BIOS提供的中断例程,包含了多个和屏幕输出相关的子程序。
int 21h是DOS提供的中断例程,包含了DOS提供的可供调用的子程序。

第14章 端口

PC机系统中与CPU通过总线相连的芯片除各种存储器外,还有以下3种芯片:
1.各种接口卡(如网卡、显卡等)上的接口芯片,它们控制接口卡进行工作;2.主板上的接口芯片,CPU通过它们对部分外设进行访问;3.其他芯片,用来存储相关的系统信息,或进行相关的输入输出处理。
这些芯片中都有一组可以由CPU读写的寄存器,它们在物理上可以处于不同芯片中,但是一下两点相同:
1.都和CPU总线相连2.CPU对它们进行读写时通过控制线向它们 所在芯片发出端口读写命令。
从cpu角度将这些寄存器当做端口,对它们统一编址,建立一个统一的端口地址空间。
PC系统中,CPU最多可以定位64KB个不同的端口,端口地址范围为0~65535
端口的读写不能用mov、push、pop等内存读写指令,只有两条:in和out,分别用于从端口读取数据和往端口写入数据。
in和out指令中只能使用ax或al来存放从端口读入的数据或发送的数据。访问8位端口用al,16位端口用ax。
对0~255号端口读写:in al,20h   out 20h,al
对256~65535的端口读写,端口号放在dx中:mov dx,3f8h  in al,dx   out dx,al

PC机中有一个CMOS RAM芯片,一般简称为CMOS

CMOS芯片中存放着当前的时间:年、月、日、时、分、秒,这6个信息的长度都为1个字节,存放单元位:
秒:0  分:2  时:4 日:7 月:8 年:9
这些数据以BCD码的方式存放
BCD码是以4位二进制数表示十进制数码的编码方法,如下表:

十进制数码 0 1 2 3 4 5 6 7 8 9
对应BCD码 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001

如数值26,用BCD码表示:0010 0110
CMOS芯片存储时间信息的单元中,高4位的BCD码表示十位,低4位的BCD码表示个位

第15章 外中断

CPU通过端口和外设进行联系:外设的输入不直接送入内存和cpu,送入相关的接口芯片的端口中;cpu向外设的输出也不是直接送入外设,而是送入端口中,再由芯片送入外设中。cpu还可以向外设输出控制命令,而这些控制命令也是先送到相关芯片的端口,再由相关的芯片根据命令对外设控制。

键盘中有一个芯片对每一个键的开关状态扫描,当按下一个键时,该芯片产生一个扫描码,扫描码说明了按下的键在键盘上的位置,被送入主板上的相关接口芯片中的寄存器,该寄存器的端口地址为60h。松下按下的键,也差生一个扫描码,说明松开的键在键盘上的位置,也被送入60h端口中。按下一个键产生的扫描码称为通码,松下一个键产生的扫描码称为断码。扫描码长度为一个字节,通码第7位为0,断码第7位为1,即:断码=通码+80h。
键盘的输入到达60h端口时,相关芯片会向CPU发出中断类型码为9的可屏蔽中断信息。CPU检测该中断信息,若IF=1,就响应中断,引发中断过程,转去执行int 9中断例程。
BIOS提供了int 9中断例程,用来进行基本的键盘输入处理,主要的工作如下:

 

上述第1、2、3都是由硬件系统完成的 ,BIOS的int 9会处理一些必要的硬件细节。
安装新的int 9中断例程时,设置int 9的段地址和偏移地址时,需要设置if=0,不响应可屏蔽中断,避免过程中发生键盘中断,出现错误。

第16章 直接定址表

地址标号和数据标号

  1. 地址标号

     1 assume cs:code2 code segment3     a: db 1, 2, 3, 4, 5, 6, 7, 84     b: dw 05 start:     mov si, offset a6           mov bx, offset b7           mov cx, 88 s:           mov al, cs:[si]9           add cs:[bx], al
    10           inc si
    11           loop s
    12
    13           mov ax, 4c00h
    14           int 21h
    15 code ends

    程序中code、a、b、start、s都是标号,仅仅表示内存单元的地址。

    注意:对于":"的地址标号,只能在代码段中使用,不能在其他段中使用。

  2. 数据标号(在代码段中使用数据标号)

     1 assume cs:code, ds: data2 code segment3     a db 1, 2, 3, 4, 5, 6, 7, 84     b dw 0    5 start:6     mov si, 07     mov cx, 8 8 s:  mov al, a[si]9     mov ah, 0
    10     add b, ax
    11     inc si
    12     loop s
    13
    14     mov ax,4c00h
    15     int 21h
    16 code ends
    17
    18 end start

    程序中的a、b是数据标号,不仅仅表示内存单元的地址,还表示了内存单元的长度。标号b代表了一个内存单元,地址为code:8,长度为两个字节。所以,如果mov al, b会报错。数据标号在编译期间被编译器直接用地址替换了,并且进行了类型(字节操作or字操作)检查比如:
     mov ax, b <==> mov ax,b
     cs:[8]mov b, 2 <==> mov word ptr cs:[8], 2
    mov al, a[si] <==> mov al,cs:0[si]
    mov al, a[bx+si+3] <==> mov al, cs:[0][bx+si+3]

  3. 数据标号(在其他段中使用)

     1 assume cs:code, ds: data2 data segment3     a db 1, 2, 3, 4, 5, 6, 7, 84     b dw 05 data ends6     7 code segment    8 start:9         mov ax, data
    10         mov ds, ax
    11
    12         mov si, 0
    13         mov cx, 8
    14 s:      mov al, a[si]
    15         mov ah, 0
    16         add b, ax
    17         inc si
    18         loop s
    19
    20         mov ax,4c00h
    21         int 21h
    22 code ends
    23 end start   

    注意:在数据段中使用数据标号,需要:使用assume将数据段和ds进行关联(这样只是将默认所访问单元的段地址都在ds中,而不是cs中);将ds指定为data段的段地址。

    现在:mov al, a[si] <==> mov al, ds:[0][si]

mov b, ax <==> mov ds:[8], ax

4.数据标号可以把标号当成数据定义

 1 data segment2     a db 1,2,3,4,5,6,7,83     b dw 04     c dw a, b ;<==> c dw offset a, offset b5 data ends6     7 data segment8     a db 1,2,3,4,5,6,7,89     b dw 0
10     c dd a, b ;<==> c dw offset a, seg a, offset b, seg b
11 data ends   

数据标号和地址标号这一部引用CSDN博主  luckyone906 的文章《汇编中的标号概念》
原文链接:https://blog.csdn.net/u011555996/article/details/80114485

offset 操作符 取得标号的偏移地址 mov ax,offset s
seg 操作符 取得标号的段地址 mov ax,seg a

依据数据直接计算出所要找的元素的位置的表,称为直接定址表。
可以通过将功能子程序的入口地址存储在直接定址表里,它们在表中的位置和功能号对应,这样程序结构清晰,便于扩充。

第17章 使用BIOS进行键盘输入和磁盘读写

int 9中断例程对键盘输入进行处理,处理完后,字符放在键盘缓冲区,切换键状态改变状态字节。然后使用int 16h中断例程读取键盘缓冲区,其中最重要的一个功能是从缓冲区读取一个键盘输入,该功能编号为0:
mov ah,0   int 16h

在int 16h中断例程中,一定有设置IF=1的指令。因为:若没有,则无法响应键入时触发的可屏蔽中断,此时若缓冲区中为空,则会陷入死循环。int 13h对磁盘进行读写。

附注:

1.Intel系列微处理器的3中工作模式

  • 实模式:工作方式相当于一个8086。
  • 保护模式:提供支持多任务环境的工作方式,建立保护机制。
  • 虚拟8086模式:可以从保护模式切换至其中的一种8086工作方式。这种方式的提供使得用户可以方便地处理在保护模式下运行一个或多个原8086程序

2.补码

以8位二进制数据说明。
用原码表示,我们可以用最高位表示符号,1表示负,0表示正,但是10000000b和00000000b均为0,出现重码。
用反码表示,先确定用00000000b~01111111b表示0~127,然后按位取反表示负数,可是0仍然重码。
用补码表示,先确定用00000000b~01111111b表示0~127,然后按位取反加1表示负数,这时
00000000b:0      11111111b+1=00000000b:0  0没有重码
00000001b:1      11111110b+1=111111111b:-1
00000010b:2      11111101b+1=111111110b:-2
011111111b:127  1000000b+1=10000000b:-127
负数的补码取反加1为其绝对值。这样上述漏掉的10000000b按位取反加1为10000000b,绝对值大小为128,故它表示-128
补码为有符号数的运算提供方便,运算后的结果仍然满足补码规则。

3.汇编编译器(masm.exe)对jmp的相关处理

  • 向前转移
    标号s在jmp...s前边,编译器里有一个地址计数器AC,编译中每读到一个字节AC就加1。在读到s后记下AC的值as,在读到jmp...s时记下AC的值aj,编译器可以利用as-aj计算出位移量disp
    若disp∈[-128,127],不管指令格式是:jmp s;jmp short s;jmp near ptr s;jmp far ptr s都转变为jmp short s所对应的机器码:EB disp(占2个字节)
    若disp∈[-32768,32767],jmp short s会产生编译错误;jmp s、jmp near ptr s将产生jmp near ptr s所对应的机器码:E9 disp(占3个字节);jmp far ptr s将产生相应的编码:EA 偏移地址 段地址(占5个字节)
  • 向后转移
    标号s在jmp...s后边,编译器先读到jmp...s记下jmp...s指令的位置和AC的值aj,并当做jmp short s来读,对于jmp short s,编译器产生EB和1个nop指令(相当于预留1个字节,存放8位disp);对于jmp s和jmp near ptr s,编译器产生EB和2个nop指令;对于jmp far ptr s,编译器产生EB和4个nop指令。当向后读到标号s时,记下AC的值as,disp=as-aj
    若disp∈[-128,127],不管指令格式是:jmp s;jmp short s;jmp near ptr s;jmp far ptr s都在前面记下的jmp...s的位置添上jmp short s对应的机器码(EB disp),此时对于jmp s和jmp near ptr s在机器码EB disp后还有1个nop;对于jmp far ptr ss在机器码EB disp后面还有3个nop
    若disp∈[-32768,32767],jmp short s会产生编译错误;jmp s、jmp near ptr s在记录的位置将产生jmp near ptr s所对应的机器码:E9 disp(占3个字节);jmp far ptr s将在记录的位置产生相应的编码:EA 偏移地址 段地址(占5个字节)

4.用栈传递参数

原理就是由调用者将需要传递给子程序的参数压入栈中,子程序从栈中取得参数。

;说明:计算(a-b)^3,a、b为字型数据
;参数:进入子程序时,栈顶存放IP,后面依次存放a、b
;结果:(dx:ax)=(a-b)^3difcube:
push bp
mov bp,sp
mov ax,[bp+4]
sub ax,[bp+6]
mov bp,ax
mul bp
mul bp
pop bp
ret 4

ret n指令含义用汇编解释:pop IP   add sp,n
因为用栈传递参数,所以调用者在调用程序的时候需要向栈中压入参数,子程序在返回时可用ret n指令将栈顶指针修改为调用前的值。调用上面的子程序前需要压入2个字型参数,所以用ret 4返回。

汇编语言(王爽老师)相关推荐

  1. 汇编语言实验十-《汇编语言-王爽老师》

    10.实验十 1.显示字符串 主要需解决的问题:字符串在显存中的地址定位 代码及注释如下: ;LAB10-1.asm assume cs:code data segmentdb 'Welcome to ...

  2. 汇编语言实验一-《汇编语言-王爽老师》

    1.实验一 1.预备知识:debug的使用 r :查看寄存器值 r ax :修改寄存器ax值 d :查看内存中的值,d 段地址:偏移地址(从指定位置,默认显示128个内存单元内容) d 1000:0 ...

  3. 汇编语言实验五-《汇编语言-王爽老师》

    5.实验五 (1).输入程序,debug调试跟踪 问题一:data段中数据不变 问题二:cs=076C.ss=076B.ds=076A 问题三:X-2.X-1 (2) 数据段以及栈均定义了两个字的数据 ...

  4. 汇编语言环境准备-《汇编语言-王爽老师》

    0.环境准备 1.DOSBox 1.1.简介 基于 x86 架构的 DOS(磁盘操作系统(Disk Operating System),是早期个人计算机上的一类操作系统.DOS是1979年由微软公司为 ...

  5. 汇编语言实验四-《汇编语言-王爽老师》

    4.实验四 1.编程传送数据到内存 编写代码 编译连接 debug调试 调试几次循环发现没有错误,可以直接在 loop 指令处使用 p 指令,跳过剩余的循环 执行结束后查看一下内存,是否正确写入 2. ...

  6. 汇编语言实验八-《汇编语言-王爽老师》

    8.实验八 首先将程序编译连接,然后debug调试跟踪. 查看一下寄存器内容 发现IP的初始值为5,说明代码段前面还有其他内容(start前面的两条程序结束指令).然后查看一下各个指令所占的内存空间 ...

  7. 汇编语言实验七-《汇编语言-王爽老师》

    7.实验七 首先查看data段中各个数据的存放位置 076A:0H-076A:53H:存放年份 076A:54H-076A:0A7H:存放收入 076A:0A8H:开始存放雇员数 编写代码如下(htt ...

  8. 汇编语言实验九-《汇编语言-王爽老师》

    9.实验九 思路大概就是一个大循环(s0)两个小循环(s1.s2),大循环执行三次,内嵌两个小循环,每一次大循环结束后,均会完成一行的字母和属性复制到目的地址.两个小循环的作用分别是复制字符到目的地址 ...

  9. 汇编语言实验六-《汇编语言-王爽老师》

    6.实验六 编写代码如下: assume cs:codesg,ss:stacksg,ds:datasg stacksg segmentdw 0,0,0,0,0,0,0,0 stacksg endsda ...

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

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

最新文章

  1. 从键盘输入一行字符,写入到string.txt文本文件中
  2. 阿里mysql同步工具otter的docker镜像
  3. [BZOJ4553][TJOI2016HEOI2016]序列(CDQ分治)
  4. node_modules
  5. firefox与ie 的javascript区别
  6. Linux出现NOKEY
  7. 面向程序员的GPGPU技术系列(1) 为什么要理解GPU体系结构?
  8. ECSHOP首页调用指定分类下的商品
  9. S32K的flexcan组件can fd使用
  10. 1.20 将多行单元格进行分栏打印 [原创Excel教程]
  11. 华为认证HCIE的含金量高吗,考试费用是多少?
  12. Java【案例6-2】 学生管理系统
  13. 计算机科学期刊催稿,围观!520 ,最“专业”的表白方式
  14. 倚杖听江声夜雨剪春韭
  15. React ref useRef 完全指南
  16. EBS 开发套件 Oracle Developer Suite 10g 安装
  17. 大同中考计算机培训,大同中考报名系统
  18. Word控件Spire.Doc 【超链接】教程(2):在 Silverlight 中插入 Word 超链接
  19. 云计算对软件工程的影响
  20. 于丹教授的360个句子(转)

热门文章

  1. android+开发平板应用,Android平板应用开发教程
  2. V5-SP6:iocomp-32/iocomp-64-crack-免安装
  3. unity webPlayer
  4. 讯飞输入法第11次作答:效率升维、场景细分、个性满足
  5. sql学生选课管理系统
  6. 【Flutter从入门到实战】⑰Flutter的主题风格、Theme、DarkTheme暗黑模式、单独给单个页面设置Theme、屏幕适配、屏幕适配工具类封装、Flutter调试使用
  7. 源码-PL/SQL从入门到精通-第四章-PL/SQL控制语句
  8. 重启打印机服务bat命令
  9. 软件测试(三)——软件测试用例篇
  10. python查询手册_Python 手册