汇编语言第5章王爽版(子程序调用指令)
汇编语言(王爽)学习记录_第五章

汇编语⾔(王爽)学习记录_第五章第五章 [bx]和loop指令1. [bx]和内存单元的描述在debug中mov ax,[0]表⽰将ds:0中的字型数据送⼊ax寄存器,⽽在编译器中此命令表⽰将0数据送⼊ax,则需改为mov ax,[bx]。
间直接是编译器将内存单元送⼊ax。
完整描述⼀个内存单元:1.内存单元的地址,2.内存单元的长度(类似al字节型,ax字型)2.looploop循环的意思3.我们定义的描述性的符号:“()”⽤“( )”表⽰⼀个寄存器或⼀个内存单元的内容,(al)、(20000H)、((ds)*16+(bx))⽐如add ax,2 描述为:(ax) = (ax)+2(X)可表⽰两种数据类型:字,字节。
取决于寄存器或具体的运算⽐如(al)表⽰字节型数据(ax)表⽰字型数据。
4.约定符号idata表⽰常量例如mov ax,[idata] 可表⽰mov ax,[1]、mov ax,[5]。
mov ax,idata可表⽰mov ax,1、 mov ax,3。
等等5.1 [bx]mov ax,[bx],可以看成是:mov bx,idata mov ax,[bx]问题5.1需要注意的是数据类型是字节型还是字型,其他就跟着题⽬看就是了。
5.2 loop指令loop指令与cx通⽤寄存器有关,执⾏loop时要进⾏两步操作:1.(cx) = (cx)-1 、2.判断(cx)不为0则执⾏标号处程序。
例:求2的12次⽅assume cs:codecode segment mov ax,2 mov cx,11s: add ax,ax loop s mov ax,4c00h int 21hcode endsend其中s是标号,当cx不为0时转⾄s处程序。
问题5.2 ⽤加法计算123*236assume cs:codecode segment mov ax,0s: add ax,123 loop s mov ax,4c00h int 21hcode endsend问题5.3 上⾯程序循环236次可以改进程序为循环123次assume cs:codecode segment mov ax,0 mov cx,123s: add ax,256 loop s mov ax,4c00h int 21hcode endsend5.3 在debug中跟踪⽤loop指令实现的循环程序问题:计算ffff:0006单元中的数乘以3结果存储在dx中 (1)考虑dx存储范围:ffff;0006是字节型数据0~255,乘3不会超过65535。
汇编语言(王爽第三版)实验5编写、调试具体多个段的程序

汇编语⾔(王爽第三版)实验5编写、调试具体多个段的程序实验5 编写、调试具体多个段的程序⼀。
将下⾯的程序编译连接,⽤Debug加载、跟踪,然后回答问题。
assume cs:code,ds:data,ss:stackdata segmentdw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987hdata endsstack segmentdw 0,0,0,0,0,0,0,0stack endscode segmentstart: mov ax,stackmov ss,axmov sp,16mov ax,datamov ds,axpush ds:[0]push ds:[2]pop ds:[2]pop ds:[0]mov ax,4c00hint 21hcode endsend start程序分析:由于是初次接触,我们逐步讲解,废话多点。
(1)此程序考察的是内存中数据段和栈段的定义。
程序共定义了1个数据段,data段,⾸先明确,在程序运⾏开始(标号start处),这个数据段就已经被定义好了,并且分配了内存空间,并赋值了。
⼀个栈段,stack。
同理这个数据段在没有被⼈⼯定义为栈结构时,也被定义好了。
并且分配了内存空间,并赋值了。
将此程序编译并连接后,使⽤debug调试,(这⾥需要注意,以下的段地址可能由于系统不同⽽有差异,主要是理解概念。
)E:\assembly>debug eee.exe-rAX=0000 BX=0000 CX=0042 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000DS=0B55 ES=0B55 SS=0B65 CS=0B67 IP=0000 NV UP EI PL NZ NA PO NC0B67:0000 B8660B MOV AX,0B66程序分析:我们什么也没执⾏,此时我们在data段定义的数据在哪?在ds:0100H处(原来讲过,程序最开始时ds:00~ds:100H是留给程序与操作系统通讯使⽤的psp内存段,参见书中p92);也就是说我们在ds:100H、0B55:100H或0B65:00处可以看见这些定义的数据。
《汇编语言》王爽老师课件

在汇编语言中,根据不同的寻址方式,可以实现不同的操作和控制 流程。
PART 03
汇编语言指令系统
数据传送指令
MOV指令
用于将数据从一个位置复制到另一个位置。例如,MOV AX, [BX]将把内存地址为BX的内容复制到AX寄存器中。
PUSH和POP指令
用于在堆栈上存储和检索数据。例如,PUSH AX将AX寄存器中的内容压入堆栈,POP AX则从堆栈顶部弹出数 据到AX寄存器中。
调试器的基本功能
01
调试器是一种用于检查程序运行时行为的工具,具有设置断点
、单步执行、查看内存和寄存器等基本功能。
常用调试器介绍
02
如OllyDbg、IDA Pro、GDB等,这些调试器各有特点,适用于
不同的平台和需求。
调试器使用技巧
03
如如何设置断点、如何单步执行、如何查看和修改内存等,这
些技巧对于调试程序至关重要。
汇编语言与机器语言是对应的,机器 语言是计算机能够直接执行的二进制 代码,而汇编语言是对机器语言的抽 象和符号表示。
汇编语言的特点
01
高效性
汇编语言能够直接描述计算机硬 件的操作,因此执行效率非常高 。
依赖性
02
03
繁琐性
汇编语言与特定的计算机体系结 构紧密相关,不同的计算机体系 结构需要使用不同的汇编语言。
调试技术应用
调试技术在程序调试中的应用
01
通过调试技术,可以定位程序中的错误,检查程序的
运行状态,理解程序的执行流程等。
调试技术在系统级编程中的应用
02 在系统级编程中,调试技术可以帮助程序员理解系统
的底层机制,检查内核和驱动程序的运行状态等。
汇编语言(王爽)第五章

汇编语⾔(王爽)第五章
第五章 [BX]和loop指令
*Loop指令
格式:loop 标号
等同步骤:(1)(cx)=(cx)-1;(2)若(cx)!=0,跳转到标号位置继续执⾏。
*Debug的相关命令及说明
g命令:g 偏移地址;使得执⾏到cs:偏移地址处停⽌;
p命令:使Debug程序⾃动重复执⾏代码中的循环指令,直到(cx)=0为⽌。
⽤Debug中直接写⼊指令,[idata]可以表⽰((段地址)*16+idata)处的值;⽽如果在汇编源代码中[idata]会被编译器masm处理为idata这个数值。
所以在汇编源代码中当使⽤⽴即数来表⽰偏移地址时,须加前缀以显式表明,⽐如:ds:[idata]。
*⽰例:计算ffff:0~ffff:b内存单元中数据的和,结果存储在dx中。
;1.每个内存单元⾥的数值是单字节类型,⽽dx是双字节寄存器
;2.总计12个内存单元的数据和最⼤为255*12<65535,不会产⽣溢出
assume cs:code
code segment
mov ax,0ffffH
mov ds,ax
mov bx,0;存储⽬标位置偏移地址
mov dx,0;初始化结果
mov ah,0;设置中转数的⾼位
mov cx,12
s:
mov al,[bx]
add dx,ax
inc bx
loop s
mov ax,4c00H
int 21H
code ends
end
*⼀段安全的空间:汇编学习过程中可以使⽤00200h~002ffh这段空间,总计256个字节。
汇编语言(王爽)

六、存储单元
将存储器划分成若干个基本的存储单位, 存储单元 称为存储单元。给每个存储单元从0开始顺序 编号,称为存储单元的地址。 0 1 0 0 1 1 1 0 0
•位(bit):计算机的最小信息单位, 即一位二进制数(0或1) •字节(Byte):1 Byte=8 bit 一个存储单元可以存储一个字节 即8bit的信息。 1KB=1024B 1GB=1024MB 1MB=1024KB 1TB=1024GB
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 0 0
MOV AX,20000
27
16位寄存器分成两个8位寄存器的使用情况
AX寄存器的逻辑结构
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
作业:
18页检测点2.1
(1)、(2)
33
四、物理地址
我们给每个存储单元给了唯一的一个 编号,这个编号就是这个内存单元的物 理地址。在8086/8088CPU中对外有20根 地址线寻址,所以其系统中的内存单元 物理地址为20位的地址编号。
指针寄存器
变址寄存器
源变址 目的变址
25
16位寄存器
• 寄存器组
控制寄存器
IP PSW CS DS SS ES
指令指针 状态标志
代码段
数据段 堆栈段 附加段
段寄存器
提 用寄存器
• 8086CPU的内部寄存器都是16位。 • 将AX、BX、CX、DX 四个寄存器称为通用寄 存器。 MOV AX,18 • 通用寄存器可分为两个独立的8位寄存器来用。 AX寄存器的逻辑结构
子程序调用指令

子程序调用指令
子程序调用指令是指一个程序在一段程序运行时,该段程序执行某个功能时,会调用由另一段子程序处理的指令的一种机器指令。
子程序调用指令的运行过程主要分为六个步骤:
1、先将书写代码时在子程序指令里声明的一个标记符(参数可以有一到多个)放入程序计数器,编程使程序跳转至对应的子程序。
2、将参数放入堆栈中。
3、程序计数器指向下一个指令(位置),将其存入返回地址寄存器中。
4、转至子程序,调用子程序中的指令,直至子程序返回跳转指令。
5、将从子程序返回的参数或结果放入程序总线中。
6、程序计数器指向堆栈中保存的返回地址,继续执行程序。
子程序调用指令的使用有很多优点,可以将程序设计的复杂性降低,提高代码的可维护性,减少重复的编码,并使程序更加结构良好和清晰。
同时,由于调用子程序时需要使用到跳转指令,也可以减少程序运行所需的时间。
然而,程序的运行效率有时也会根据子程序的大小和复杂性以及条件的多少而有所降低。
汇编语言-王爽

汇编语⾔-王爽前⾔学习汇编的两个最根本的⽬的:充分获得底层编程的体验,深刻理解机器运⾏程序的机理。
任何不以循序渐进的⽅式进⾏的学习,都将出现盲⽬探索和不成系统的情况,最终学习到的也⼤都是相对零散的知识,并不能建⽴起⼀个系统的知识结构。
⾮循序渐进的学习,也达不到循序渐进学习所能达到的深度,因为后者是步步深⼊的,每⼀步都以前⼀步为基础必须遵守的原则:①没有通过监测点不要向下学习②没有完成当前的实验不要向下学习③每⼀个实验都是后续内容的基础,实验的任务必须独⽴完成④本书的教学重⼼是:通过学习关键指令来深⼊理解机器⼯作的基本原理,培养底层编程意识和思想我们必须通过⼀定的编程实践,体验⼀个裸机的环境,在⼀个没有操作系统的环境中直接对硬件编程第1章基础知识汇编语⾔是直接在硬件之上⼯作的编程语⾔机器语⾔/机器指令集是机器指令的集合寄存器是CPU中可以存储数据的器件编译器能够将汇编指令转换成机器指令的翻译程序汇编语⾔由以下3类指令组成:1.汇编指令:机器码的助记符,由对应的机器码(核⼼) <汇编指令是机器指令便于记忆的书写格式>2.伪指令:没有对应的机器码,由编译器执⾏,计算机并不执⾏3.其他符号:+ - * /要想让⼀个CPU⼯作,就必须向它提供指令和数据。
指令和数据在存储器中存放,也就是我们平时所说的内存CPU要从内存中读数据,⾸先要指定存储单元的地址,CPU在读写数据时还要指明。
它要对哪个器件进⾏哪种操作所以CPU要想进⾏数据的读写,必须和外部器件进⾏下⾯3类信息的交互->存储单元的地址(地址信息)器件的选择,读或写的命令(控制信息)读或写的数据(数据信息)指令和数据没有任何区别,都是⼆进制信息。
CPU在⼯作的时候把有的信息看作数据,为同样的信息赋予了不同的意义1 Byte = 8 bit = 8个⼆进制位 = 8位⼆进制数据在计算机中专门有连接CPU和其他芯⽚的导线,通常称为总线,总线从逻辑上分为3类,地址总线、控制总线、数据总线(1)CPU通过地址线将地址信息3发出(2)CPU通过控制线发出内存读命令,选中存储器芯⽚并通知它将要从中读取数据(3)存储器将3号单元中的数据8通过数据线送⼊CPUCPU是通过地址总线来指定存储器单元的10根导线可以传送10位⼆进制数据。
王爽《汇编语言》 第5章 [BX]和LOOP指令
![王爽《汇编语言》 第5章 [BX]和LOOP指令](https://img.taocdn.com/s3/m/5899f8bdc77da26925c5b064.png)
(21006H)=BEH
CS:CODE : SEGMENT 循环控制指令LOOP 二、循环控制指令 MOV AX,2 , 作计数器控制程序的循环。 用CX作计数器控制程序的循环。 作计数器控制程序的循环 MOV CX,11 , 格式: 格式:LOOP 标号 ;CX≠0循环 循环 S: ADD AX,AX : , 功能: )-1; 功能:当CX≠0时,( )=(CX)- ;转移到标号处 时,(CX) ( )- LOOP S 循环执行。 利用 循环执行。 利用LOOP指令编程计算 12 指令编程计算2 指令编程计算 MOV AX,4C00H , INT 21H 2:编程,用加法计算123×236,结果存在AX中 例2:编程,用加法计算123×236,结果存在AX中。 CODE ENDS END ASSUME CODE CX和LOOP指令配合实现循环功能的三个要点: 和 指令配合实现循环功能的三个要点: 指令配合实现循环功能的三个要点 1、在CX中存放循环次数 、 中存放循环次数 2、LOOP指令中的标号所标识地址要在前面 、 指令中的标号所标识地址要在前面 3、要循环执行的程序段写在标号和LOOP指令之间。 、要循环执行的程序段写在标号和 指令之间。 指令之间
七、一段安全的空间
汇编语言程序直接面向机器, 汇编语言程序直接面向机器,如果我们要向 内存空间写入数据时, 内存空间写入数据时,要保证所写入的内存中没 有重要的数据,否则会影响系统的正常运行, 有重要的数据,否则会影响系统的正常运行,在 一般的PC机中都不使用 机中都不使用0: 一般的 机中都不使用 :200—0:300这段内存 : 这段内存 空间,所以我们可以放心使用这段安全的空间。 空间,所以我们可以放心使用这段安全的空间。
一、[BX]
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
POP CX
POP BX POP AX RET PROG ENDP
二、主程序与过程的参数传递方式
主程序-子程序的参数传递: 入口参数—— 也称入口条件,是指主程序调用子程序 前,为子程序内部数据处理准备所需的预置值;
出口参数—— 也称出口条件,是子程序返回主程序后, 把子程序处理的结果传递给主程序的数据。
例5-3多字数相加的程序(堆栈传递子程序参数) RET指令中参数的应用例子
data va11 va12 buffer len data stack
segment dw 9898h,7676h,5454h,3232h ;被加数 dw 9898h,7676h,5454h,3232h ;加数 dw 4 dup(?) ;和 equ $-buffer ends segment stack dw 100 dup(?) stack ends code segment assume cs:code,ds:data,ss:stack,es:data
子程序返回指令(RET)
放在子程序的末尾,它使子程序在执行完任务后将堆栈中的 断点弹出,控制程序返回主程序继续执行被打断的程序。而 返回地址(断点)就是子程序调用时入栈保护的断点地址IP (段内调用)或IP和CS值(段间调用)。通常,RET指令的类 型是隐含的,它自动与子程序定义时的类型相匹配,如果是 段内,返回时将栈顶的一个字弹给IP寄存器;如为段间,返 回时先从栈顶弹出一个字给IP,接着再弹出一个字给CS。但 是,当采用间接调用时,必须注意:保证CALL指令的类型与 过程中RET指令的类型匹配,以免发生错误。例如CALL WORD PTR[BX]只能是段内调用,而CALL DWORD PTR[BX]能够调用 一个远过程(段间调用),这样RET才能够识别返回类型。
DATA SUM DATA STACK STACK CODE START:
CODE END
SEGMENT 通过堆栈——功能最强/最灵活/最复杂 DB 0 ENDS SEGMENT DB 100 DUP(?) ENDS Spr PROC SEGMENT PUSH BP ASSUME DS:DATA,SS:STACK,CS:CODE MOV BP, SP MOV AX,DATA MOV AX, [BP+6] MOV DS,AX MOV BX, [BP+4] MOV AL, 1 ADD AL, BL MOV BL, 2 OR AL, 30H MOV AH,0 MOV DL,AL MOV BH,0 MOV AH,2 PUSH AX INT 21H PUSH BX MOV SUM, AL CALL SPR POP BP POP BX RET POP AX Spr ENDP MOV AH,4CH INT 21H ENDS START
DATA SUM D1 D2 DATA STACK
STACK CODE START:
CODE
SEGMENT 通过变量传送 DB 0 DB ? DB ? ENDS SEGMENT DB 100 DUP(?) ENDS SEGMENT ASSUME DS:DATA,SS:STACK,CS:CODE MOV AX,DATA SPROG PROC MOV DS,AX MOV AL, D1 MOV D1, 1 ADD AL, D2 MOV D2, 2 OR AL, 30H CALL SPROG MOV SUM, AL MOV AH,4ch MOV dl,al INT 21H MOV ah,2 ENDS INT 21h END START RET SPROG ENDP END START
主程序和子程序间的关系:调用子程序的程序称为主调程序或 主程序,被调用的程序称为子程序。 2、程序中使用子程序的好处 子程序作为一个功能性模块,供一个程序甚至多个程序使用: 可以简化源程序结构; 提高程序的可读性与可维护性; 有利于代码复用; 提高程序的设计效率。
5.2 子程序的定义、调用和返回
1、子程序的定义:由子程序定义伪指令PROC和ENDP来完成。其 格式如下:
ENDS END begin
子程序的位置通常在主程序的所有可 执行指令之前或之后,不能放在主程 序的可执行指令序列内部,否则会破 坏主程序结构
5.3子程序的现场保护与参数传递
PROG PROC PUSH AX
一、信息的保护与恢复
PUSH BX
PUSH CX PUSH DX ┆ POP ┆ DX ;保护现场 例如:若子程序PROG中 改变了寄存器AX,BX, CX,DX的值,则可采用 此方法保护和恢复现场。 ;恢复现场 ;返回断点处
Call
add64 mov ah,4ch int 21h main endp ;主程序结束
;子过程ADD64开始 add64 proc push bp ; mov bp,sp push bx push si push di push cx pushf ;保存现场 mov si,[bp+4] ; mov bx,[bp+6] mov di,[bp+8] mov cx,[bp+10] ;读取参数 cld
;子程序定义 ;返回
子程序结构示例
1.多处调用完成同一功能的子 程序: code SEGMENT start: … CALL sub … CALL sub … MOV AH, 4CH INT 21H sub PROC 、、 、、 RET sub ENDP code ENDS end start
2.模块化程序设计:多个子程序的调用
演示
5.2 子程序的定义、调用和返回(续)
子程序调用指令(CALL)
CALL指令分成4种类型 CALL子程序名 CALL r16/m16 CALL far ptr子程序 CALL far ptr mem ;段内直接调用 ;段内间接调用 ;段间直接调用 ;段间间接调用
CALL指令需要保存返回地址: – 段内调用——偏移地址IP入栈 SP←SP-2,SS:[SP]←IP – 段间调用——偏移地址IP和段地址CS入栈 SP←SP-2,SS:[SP]←CS SP←SP-2,SS:[SP]←IP
例5-2:多字节数相加的程序(寄存器传递过程参数)
data num1 num2 len data stack
segment db 01h,02h,03h,04h,05h,06h db 0ffh,07h,0ffh,03h,01h,06h equ $- num2 ends segment stack dw 100 dup(?) stack ends code segment assume cs:code,ds:data,ss:stack
例5-1:分别用三种参数传递方法编写求1+2的和的程 序。要求将结果送到内存单元,并显示。
DATA SUM DATA STACK STACK CODE START:
CODE
SEGMENT 通过寄存器传送 DB 0 ENDS SEGMENT DB 100 DUP(?) ENDS SEGMENT ASSUME DS:DATA,SS:STACK,CS:CODE MOV AX,DATA Subprog PROC MOV DS,AX ADD AL, BL MOV AL, 1 OR AL, 30H MOV BL, 2 MOV SUM, AL CALL subprog Mov dl,al mov ah,4cH Mov ah,2 int 21h Int 21h ENDS RET END START sub ENDP
第5章
结构化程序设计
教学基本内容
5.1 子程序的概念 5.2 子程序的定义、调用和返回 ** 5.3 子程序的现场保护与参数传递** 5.4 子程序设计 *
5.5 子程序的嵌套与递归调用
5.6 宏汇编程序设计
5.1 子程序的概念
1、子程序:在程序设计中,我们会发现一些多次无规律重复的 程序段或语句序列。解决此类问题一个行之有效的方法就是将 它们设计成可供反复调用的独立的子程序结构,以便在需要时 调用。在汇编语言中,子程序又称过程。 过程(子程序):是指功能相对独立的一段程序。
Start: mov ax,data mov ds,ax
lea si,num1 lea di,num2 mov cx,len
call mpadd
mov ah,4ch int 21h
Mpadd proc push ax push cx push si push di jcxz exit clc Next: mov al,[di] adc [si],al inc si inc di loop next Exit: pop di pop si pop cx pop ax ret Mpadd endp Code ends end start
总结
子程序是提高程序设计效率的良好手段,也为模块化设计提供 了很好的基础。
在子程序设计中 • 要明确地定义出这个子程序的入口参数和出口参数,使调用 者能方便地使用子程序。 • 在子程序中要合理地保存主程序和子程序都用到的寄存器和 存储单元,以使主程序能正确地运行。
总结
注意:前面所介绍的三种传递参数的方法,并不是固定不变的。 即它们是可以综合使用的。要按照实现的需要和具体情况的不 同,可以使用其中一种方式,也可以同时使用几种混合的方式, 有的时候还可能并不需要参数的传递。 总之,调用程序和子程序之间的参数传递,的确十分重要, 参数不宜使用太多。参数选择的适当,可以简化程序设计。 参数确定之后,就是如何进行传递的问题。无论采用哪一 种传递方式,都应该保证正确无误的传递。这是调用程序和子 程序的协调关系。这也是在子程序设计中需要认真解决的问题。
参数传递的基本方法有:
(1)寄存器法:通过CPU寄存器传递参数。传递数据方便、快 捷,但所能传递的数据长度和个数都有限。
(2)变量法:通过内存单元(组)传递参数。传递数据的长度 和个数可不受限制,程序设计比较灵活。 (3)堆栈法:通过堆栈传递参数。用堆栈保存所要传递的数 据或存储地址,利用堆栈数据存取的特点,是常用的参数传 递方法。