汇编语言程序设计 实例详解

合集下载

第4章汇编语言程序设计PPT教学课件

第4章汇编语言程序设计PPT教学课件

图 分支程序结构流程图
2020/12/11
《单片机应用技术》教学课件
12Leabharlann 第4章 汇编语言程序设计条件满足? Y
A
4.2.2 分支程序结构
第4章 汇编语言程序设计
目的:1.进一步熟悉指令系统 2.会编写简单的程序 3.上机训练
内容:4.1 汇编语言程序设计概述
4.2 三种程序结构 4.3 程序设计举例
2020/12/11
《单片机应用技术》教学课件
1
第4章 汇编语言程序设计
4.1 汇编语言程序设计概述
所谓程序设计,就是按照给定的任务要求,编写 出完整的计算机程序。要完成同样的任务,使用的方 法或程序并不是唯一的。
汇编后: (1000H)=12H (1001H ) = 34H
(1002H ) = 00H ( 1003H ) = ABH (1004H ) =00H (1005H) =0AH
2020/12/11
《单片机应用技术》教学课件
7
第4章 汇编语言程序设计
• (6)定义存储区伪指令DS
• 功能:从指定地址开始预留一定数量的内 存单元,以备源程序执行过程中使用。预
(4) 编写源程序
(5) 程序优化。
(6)上机调试、修改和最后确定源程序。
2020/12/11
《单片机应用技术》教学课件
10
第4章 汇编语言程序设计
4.2.1 顺序程序设计
顺序结构程序是一种最简单、最基本的程序,按照程序编 写的顺序依次执行。
【例4-1】两个多字节数加法
1.两个三字节无符号相加,其中被加数在内部RAM的 50H、51H和52H单元中;加数在内部RAM的53H、54H和 55H单元中;要求把相加之和存放在50H、51H和52H单元中 进位存放在位寻址区的00H位中。

汇编语言程序例题知识讲解

汇编语言程序例题知识讲解
数108169032
第一遍101690328
第二遍169032108
第三遍903216108
程序流程图如图5.9所示。
DATASEGMENT
BUFDW 3,-4,6,7,9,2,0,-8,-9,-10,20
N=($-BUF)/2
DATAENDS
STACKSEGNMENT STACK
DB 200 DUP(0)
DI存放ASCII码首地址
出口参数:
转换后的字符串存放在以DI作指针的字节存贮区中
程序清单:
DATASEGMENT
NUM8DB93H
NUM16DW0ABCDH
ASCBUFDB20DUP(0)
DATAENDS
CODESEGMENT
ASSUME DS:DATA,CS:CODE,SS:STACK
START:MOVAX,DATA
题目分析:根据数学中绝对值的概念知道,一个正数的绝对值是它本身,而一个负数的绝对值是它的相反数;要计算一个数的相反数,需要完成减法运算,即用0减去这个数。8086/8088指令系统中有专门的求相反数的指令NEG。
DATASEGMENT
XDB -25
RESULTDB ?
DATAENDS
CODESEGMENT
程序流程如图下所示。
DATASEGMENT
TABDW P1,P2,P3,P4,P5,P6,P7,P8
NDB 5
DATAENDS
STACKSEGMENT
DB 200 DUP(0)
STACKENDS
CODESEGMENT
ASSUME DS:DATA,SS:STACK,CS:CODE
START:MOVAX,DATA
MOVDS,AX

汇编语言编程实例

汇编语言编程实例

汇编语言编程实例一、引言汇编语言是计算机硬件和软件之间的桥梁,它是一种低级语言,可以直接控制计算机硬件。

汇编语言编程可以让程序员更加深入地理解计算机的工作原理,从而实现更高效的程序。

本文将介绍几个汇编语言编程实例,涉及到基本的输入输出、循环、条件判断、数组等知识点。

在这些实例中,我们将使用NASM汇编器进行编译和链接。

二、基本输入输出1. 输出字符串在汇编语言中,我们可以使用系统调用来进行输入输出操作。

在Linux 系统中,输出字符串的系统调用为write。

下面是一个输出字符串的示例程序:```section .datamsg db 'Hello, World!',0xa ;定义一个字符串len equ $-msg ;获取字符串长度section .textglobal _start_start:mov eax, 4 ;write系统调用号为4mov ebx, 1 ;文件描述符为1(标准输出)mov ecx, msg ;要输出的字符串地址mov edx, len ;要输出的字符数int 0x80 ;调用系统调用mov eax, 1 ;exit系统调用号为1xor ebx, ebx ;退出状态码为0int 0x80 ;调用系统调用退出程序```2. 输入数字类似地,在Linux系统中,输入数字的系统调用为read。

下面是一个输入数字的示例程序:```section .datamsg db 'Please enter a number: ',0xa ;提示信息len equ $-msg ;获取字符串长度buf resb 1 ;定义一个字节的缓冲区section .textglobal _start_start:mov eax, 4 ;write系统调用号为4mov ebx, 1 ;文件描述符为1(标准输出)mov ecx, msg ;要输出的字符串地址mov edx, len ;要输出的字符数int 0x80 ;调用系统调用mov eax, 3 ;read系统调用号为3mov ebx, 0 ;文件描述符为0(标准输入)mov ecx, buf ;缓冲区地址mov edx, 1 ;要读取的字节数int 0x80 ;调用系统调用sub al, '0' ;将ASCII码转换成数字值```三、循环和条件判断1. 计算1到100的和下面是一个计算1到100的和的示例程序,其中使用了循环和条件判断:```section .datasum dd 0 ;定义一个双精度浮点型变量sumsection .textglobal _start_start:xor eax, eax ;eax清零,作为计数器和累加器使用loop_start:inc eax ;eax自增1,相当于i++cmp eax, 100+1 ;比较i是否大于100,注意要加1je loop_end ;如果i等于101,跳转到loop_endadd dword [sum], eax ;将i加到sum中jmp loop_start ;跳转到loop_startloop_end:mov eax, dword [sum] ;将sum赋值给eax,作为返回值mov ebx, 1 ;exit系统调用号为1int 0x80 ;调用系统调用退出程序```2. 判断一个数是否为素数下面是一个判断一个数是否为素数的示例程序,其中使用了循环和条件判断:```section .datamsg db 'Please enter a number: ',0xa ;提示信息len equ $-msg ;获取字符串长度buf resb 1 ;定义一个字节的缓冲区section .textglobal _start_start:mov eax, 4 ;write系统调用号为4mov ebx, 1 ;文件描述符为1(标准输出)mov ecx, msg ;要输出的字符串地址mov edx, len ;要输出的字符数int 0x80 ;调用系统调用mov eax, 3 ;read系统调用号为3mov ebx, 0 ;文件描述符为0(标准输入)mov ecx, buf ;缓冲区地址mov edx, 1 ;要读取的字节数int 0x80 ;调用系统调用sub al, '0' ;将ASCII码转换成数字值check_prime:xor ebx, ebx ;ebx清零,作为除数使用mov ecx, eax ;将eax的值赋给ecx,作为被除数使用inc ebx ;将ebx自增1,相当于除数加1cmp ebx, ecx ;比较除数是否大于被除数jge is_prime ;如果除数大于等于被除数,跳转到is_prime xor edx, edx ;edx清零,作为余数使用div ebx ;将ecx/ebx的商放在eax中,余数放在edx中 cmp edx, 0 ;判断余数是否为0je not_prime ;如果余数为0,跳转到not_primejmp check_prime ;跳转到check_primenot_prime:mov eax, 4 ;write系统调用号为4mov ebx, 1 ;文件描述符为1(标准输出)mov ecx, not_prime_msg ;要输出的字符串地址mov edx, not_prime_len ;要输出的字符数int 0x80 ;调用系统调用exit:mov eax, 1 ;exit系统调用号为1xor ebx, ebx ;退出状态码为0int 0x80 ;调用系统调用退出程序not_prime_msg db 'The number is not prime.',0xa ;提示信息not_prime_len equ $-not_prime_msgis_prime:mov eax, 4 ;write系统调用号为4mov ebx, 1 ;文件描述符为1(标准输出)mov ecx, is_prime_msg ;要输出的字符串地址mov edx, is_prime_len ;要输出的字符数int 0x80 ;调用系统调用jmp exit ;跳转到exitis_prime_msg db 'The number is prime.',0xa ;提示信息is_prime_len equ $-is_prime_msg```四、数组1. 计算数组的和下面是一个计算数组的和的示例程序:```section .dataarr dd 1, 2, 3, 4, 5 ;定义一个双精度浮点型数组arrn equ ($-arr)/4 ;获取数组长度section .textglobal _start_start:xor eax, eax ;eax清零,作为计数器和累加器使用xor ecx, ecx ;ecx清零,作为数组下标使用loop_start:cmp ecx, n ;比较ecx是否大于等于njge loop_end ;如果ecx大于等于n,跳转到loop_endadd eax, dword [arr+ecx*4] ;将arr[ecx]加到eax中inc ecx ;将ecx自增1,相当于下标加1jmp loop_start ;跳转到loop_startloop_end:mov ebx, eax ;将sum赋值给ebx,作为返回值mov eax, 1 ;exit系统调用号为1xor ecx, ecx ;退出状态码为0int 0x80 ;调用系统调用退出程序```2. 查找数组中的最大值下面是一个查找数组中的最大值的示例程序:```section .dataarr dd 10,20,30,-40,-50,-60,-70,-80,-90,-100 ;定义一个双精度浮点型数组arrn equ ($-arr)/4 ;获取数组长度section .textglobal _start_start:mov eax, dword [arr] ;将arr[0]赋值给eax,作为最大值使用xor ecx, ecx ;ecx清零,作为数组下标使用loop_start:cmp ecx, n ;比较ecx是否大于等于njge loop_end ;如果ecx大于等于n,跳转到loop_endcmp eax, dword [arr+ecx*4] ;比较eax和arr[ecx]jge loop_next ;如果eax大于等于arr[ecx],跳转到loop_next mov eax, dword [arr+ecx*4] ;将arr[ecx]赋值给eax,更新最大值loop_next:inc ecx ;将ecx自增1,相当于下标加1jmp loop_start ;跳转到loop_startloop_end:mov ebx, eax ;将max赋值给ebx,作为返回值mov eax, 1 ;exit系统调用号为1xor ecx, ecx ;退出状态码为0int 0x80 ;调用系统调用退出程序```五、总结本文介绍了几个汇编语言编程实例,涉及到基本的输入输出、循环、条件判断、数组等知识点。

第4章 汇编语言程序设计

第4章  汇编语言程序设计

因此, 因此,对例子中的存储器地址作如下运 算: SUM+2 CYCLE-5 NOT_DONE-GO 是有效的表达式。 是有效的表达式。而 SUM-CYCLE
(2)逻辑运算符 逻辑运算符是按位操作的AND、OR、 、 逻辑运算符是按位操作的 、 XOR和NOT。 和 。 1010 1010 1010 1010B AND 1100 1100 1100 1100B=1000 1000 1000 1000B 1100 1100 1100 1100B OR 1111 0000 1111 0000B=1111 1100 1111 1100B NOT 1111 1111 1111 1111B=0000 0000 0000 0000B
ASSUME CS:MY_CODE, ;规定 和DS 规定CS和 : 的内容 DS:MY_DATA : PORT_VA1 EQU 3 ;端口的符号名 GO: MOV AX, MY_DATA ;DS : 初始化为MY_DATA 初始化为 MOV DS, AX MOV SUM, 0 ;清SUM单元 单元
变量可以具有以下几种寻址方式: 变量可以具有以下几种寻址方式: ① 直接寻址 ② 基址寻址 变址(索引) ③ 变址(索引)寻址 ④ 基址变址寻址
2.运算符(Operators) .运算符( ) 算术运算符( Operators) ① 算术运算符(Arithmetic Operators) 逻辑运算符( Operators) ② 逻辑运算符(Logical Operators) 关系运算符( Operators) ③ 关系运算符(Relational Operators) 分析运算符( Operators) ④ 分析运算符(Analytic Operators) 合成运算符( Operators) ⑤ 合成运算符(Synthetic Operators)

汇编程序设计举例

汇编程序设计举例
② 循环体:重复运行的部分,其中还包含了工作部分和循环控 制部分。工作部分进行相应的操作,而循环控制部分则保证在不满足 循环条件时,跳出循环。
③ 循环结束条件:在循环体中包括了循环结束条件运算部分。 每循环一次除了工作部分进行相应的操作外,循环条件部分还要通过 运算,得出当前循环的状态,以便在适当的条件下结束循环。
2. 循环的类型
循环体的结构依照问题的不同,一般可以分为 两种类型:
① 先判断后处理 ② 先处理后判断
3. 控制循环次数的方法
有三种:用计数控制循环,用条件控制循环和用 逻辑变量控制循环。其中,前两种方法用的最多。 ①用计数控制循环
对于循环次数已知的程序,或是在进入循环前可 由某变量确定循环次数的程序,通常用计数器来控 制循环。(用LOOP指令)
(1)利用寄存器。这是一种最常见方法,把所 需传递的参数直接放在主程序的寄存器中传递 给子程序。
(2)利用存储单元。这种参数传递方法,把所 需传递的参数直接放在子程序调用指令代码之 后。
(3)利用堆栈。这种方法将参数压入堆栈,在 子程序运行时从堆栈中取参数。
[例2] 求绝对值 求AX寄存器和BX寄存器中两个无符号数之差
的绝对值,结果放在内存(偏移地址为2800)单元 中。
分析:利用比较指令,判断谁大谁小,然后大 数减小数。
CLC SUB AX,BX JC AA MOV DI,2800H MOV [DI],AX JMP EXIT AA: SUB BX,AX MOV DI,2800H MOV [DI],BX EXIT: MOV AH,4CH INT 21H
1 x>0
[例3] 有一符号函数如下 y=f(x)= 0 x=0
开始
-1 x<0

汇编语言程序设计实例

汇编语言程序设计实例

汇编语言程序设计实例汇编语言是一种非常底层的编程语言,它允许程序员直接与计算机硬件进行交互。

汇编语言程序设计通常用于需要高性能或者对硬件有特定需求的场合。

以下是一些汇编语言程序设计的实例,以帮助理解其基本结构和应用。

实例一:数据传输在汇编语言中,数据传输是最基本的操作之一。

以下是一个简单的数据传输程序实例,它将一个立即数(即直接给出的数值)移动到寄存器中:```assemblymov ax, 1234h ; 将十六进制数1234h移动到ax寄存器```实例二:算术运算汇编语言支持基本的算术运算,如加法、减法、乘法和除法。

以下是一个进行加法运算的例子:```assemblymov ax, 5 ; 将数值5移动到ax寄存器add ax, 3 ; 将数值3加到ax寄存器中```实例三:条件跳转条件跳转是控制程序流程的重要手段。

以下是一个基于条件跳转的简单程序,它检查ax寄存器的值是否为0,并根据结果跳转到不同的代码段:```assemblymov ax, 0 ; 将数值0移动到ax寄存器jz zero ; 如果ax为0,则跳转到标签zero; 继续执行其他代码...zero:; 如果ax为0,执行这里的代码```实例四:循环结构循环结构在汇编语言中实现起来较为复杂,但可以通过重复使用跳转指令来模拟。

以下是一个简单的循环结构实例,它将ax寄存器的值减1,直到值为0:```assemblystart_loop:dec ax ; 将ax寄存器的值减1jnz start_loop ; 如果ax不为0,跳回start_loop```实例五:字符串处理汇编语言程序设计中,字符串处理是一个常见的任务。

以下是一个将字符串从源地址复制到目标地址的程序:```assemblymov si, source ; 将源字符串的地址移动到si寄存器mov di, dest ; 将目标地址移动到di寄存器mov cx, length ; 将字符串的长度移动到cx寄存器copy_loop:movsb ; 从si复制一个字节到diloop copy_loop ; 减少cx的值并重复循环直到cx为0```实例六:子程序调用在汇编语言中,子程序是一种将代码封装成模块化单元的方法。

汇编语言程序设计实验篇(emu8086)

汇编语言程序设计实验篇(emu8086)

1.汇编语言程序设计实验篇1.1.汇编系统软件简介Emu8086-Microprocessor Emulator是集源代码编辑器、汇编/反汇编工具以及debug 的模拟器。

它能模拟一台"虚拟"的电脑运行程序,拥有独立的“硬件”,避免访问真实硬件。

该软件兼容Intel的下一代处理器,包括PentiumII、Pentium4。

利用该软件提供的调试工具,能够单步跟踪程序,观察程序执行过程中寄存器、标志位、堆栈和内存单元的内容。

1.1.1创建程序 TEMPLATE程序本章与指令相关的实验都是用COM TEMPLATE类型的程序完成的。

打开emu8086,在“welcome…”对话框中,单击按钮,创建文件。

在“choose code template”对话框中,选择“COM template-simple and tiny executable file format, pure machine code.”后,单击按钮。

在如所示的编辑界面中,在“;add your code here”部分输入相应的指令,第一条指令默认的偏移地址为100h。

输入全部指令后,单击按钮,保存相应的程序段。

2.EXE TEMPLATE程序本章与DOS功能调用和汇编源程序相关的实验都是用EXE TEMPLATE程序完成的。

打开emu8086,在“welcome…”对话框中,单击按钮,创建文件。

在“choose code template”对话框中,选择“EXE template-advanced executable file.header: relocation, checksum.”后,单击按钮。

在如图所示的编辑界面中,已经可以给出了源程序的框架,包含数据段、堆栈段和代码段的定义以及必要的功能调用等,在“add your data here”和“;add your code here”部分可以分别输入相应的变量定义和指令。

汇编语言程序设计 实例详解

汇编语言程序设计 实例详解

_c_int00: start:
Done:
.text B NOP NOP SSBX STM STM RPT MVPD STM STM STM RPTZ MAC STH B .end
start
FRCT #0,SWWSR #x,AR1 #7 table,*AR1+ #x,AR2 #a,AR3 #y,AR4 A,#3 *AR2+,*AR3+,A A,*AR4 done
DARAM2: origin = 0200h,length = 100h
}
SECTIONS
{
.data :> RAM
PAGE 0
.text :> RAM
PAGE 0
PROM :> RAM1 PAGE 0
.bss :> DARAM1 PAGE 1
DATA :> DARAM2 PAGE 1
}
[例7-4]使用C54汇编语言编程计算z1=x1+y1、z2=x1-y1,z3=x1* Z4=x2*y2,观察计算结果。其中,x1=20,y1=54,x2=0.5,y2=-0.5
.bss a,20
.bss x,20
DATA
.bss y,20 .usect “DATA”,20
.text
_c_int00: B start
NOP
NOP
start: STM #a,AR1
;a[20]={0,1,2,3,4,5,6,7,8,9,10,
;11,12,13,14,15,16,17,18,19}
.text
_c_int00: B
start
NOP
start:
LD
#x1,DP

第4章汇编语言程序设计3(常见程序设计举例)精品PPT课件

第4章汇编语言程序设计3(常见程序设计举例)精品PPT课件

;实际字符数送CL ;第一个字符送AL ;暂存在CH
;第一个字符是负
;不是,转NEXT1 ;字符数减1
;指向第一个数字字符 ;清零AX,存二进制数
;若(CL)=0,转NEXT2 ;取字符 ;转换成BCD码 ;加到中间结果上
10
NEXT2:
NEXT3: CHANGE ; CODE
MOV MUL INC JMP MOV AND ADD CMP JNZ NEG MOV RET ENDP
ENDS END
DX,10 DX BX SHORT LP1 DL,[BX] DL,0FH AX,DX CH,’-’ NEXT3 AX [DI],AX
START
;*10 ;指向下一个字符
;取个位数 ;个位ASCII→未组合BCD ;加个位数,(AX)=001AH
;是’-’? ;该数非负,转NEXT3 ;若为负,求补 ;存二进制结果
16
AGAIN1: NEXT1: AGAIN2: NEXT2:
;计算百位的个数 MOV DL,0 SUB AX,1000 JC NEXT1 INC DL JMP AGAIN1 ADD AX,1000 MOV [BX],DL ;计算百位的个数 MOV DL,0 SUB AX,100 JC NEXT2 INC DL JMP AGAIN2 ADD AX,100 MOV [BX+1],DL
;(SP)=0052H ;(AX)=25AFH ;(DI)=0002H STRING-4;(DI)=0005H ;(DX)=25AFH
BCD→二进制数在本例中采用用以下方法:
((((0+千位数)*10+百位数)*10)+十位数)*10+个位数
第一次中间结果

汇编语言小程序例子

汇编语言小程序例子

盛年不重来,一日难再晨。

及时宜自勉,岁月不待人。

1.编写统计AX中1、0个数的源程序。

1的个数存入CH,0的个数存入CL。

CODE SEGMENTASSUME CS:CODESTART: MOV CX, 0MOV DX,17AA1: SUB DX, 1JZ AA3SHL AX, 1JNC AA2INC CHJMP AA1AA2: INC CLJMP AA1AA3: MOV AH,4CHINT 21HCODE ENDSEND START2.编写比较两个字符串STRING1和STRING2所含字符是否完全相同的源程序,若相同则显示“MATCH”,若不相同则显示“NO MATCH”。

程序:DATA SEGMENTR1 DB 'MATCH',0AH,0DHR2 DB 'NO MATCH',0AH,0DH STRING1 DB 'XXXXX'N1 EQU $-STRING1STRING2 DB 'YYYYY'N2 EQU $-STRING2DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA START: MOV AX,DATAMOV DS,AXMOV AX,N1CMP AX,N2JNZ AA1ADD AX,1LEA SI,STRING1LEA DI,STRING2AA2: MOV BL,[SI]MOV BH,[DI]INC SIINC DISUB AX,1JZ AA3CMP BL,BH JZ AA2JMP AA1AA3: LEA BX,R1 MOV CX,7 AA4: MOV DL,[BX] INC BXMOV AH,2INT 21HLOOP AA4JMP EAA1: LEA BX,R2 MOV CX,10 AA5: MOV DL,[BX] INC BXMOV AH,2INT 21HLOOP AA5INT 21HCODE ENDSEND START3.从键盘读入一个四位的十六进制数,CRT显示等值的二进制数.由于每个十六进制数位对应4个二进制,所以每读入一个十六进制位后,即可将其对应的4个二进制位依次输出。

汇编语言典型例子详解经典汇编程序案例

汇编语言典型例子详解经典汇编程序案例

汇编语言典型例子详解经典汇编程序案例汇编语言是一种低级程序设计语言,它直接操作计算机的硬件资源,为计算机执行指令提供了底层的支持。

在计算机发展的早期阶段,汇编语言是主要的编程语言之一,它的应用广泛而重要。

本文将详细解析汇编语言的典型例子,并结合经典的汇编程序案例进行详细讲解。

1. 汇编语言的介绍汇编语言是一种接近机器指令的低级语言,它使用助记符将机器语言表示成易于理解和编写的形式。

与高级语言相比,汇编语言更加底层,可以直接操作计算机的寄存器、内存等硬件资源。

汇编语言的执行速度快,对硬件资源的控制更为精确,因此在一些对性能要求较高的应用中仍然得到广泛应用。

2. 经典汇编程序案例:斐波那契数列斐波那契数列是一个经典的数学问题,定义如下:第一个数为0,第二个数为1,从第三个数开始,每个数都等于前两个数之和。

用数学公式表示就是:Fn = Fn-1 + Fn-2。

现在我们将通过汇编语言来实现斐波那契数列的计算。

首先,我们需要定义一段连续的内存空间用来存储计算结果。

假设我们使用存储器的地址0x1000开始的连续10个字节的空间来保存斐波那契数列的前10个数字。

我们可以使用寄存器来保存地址0x1000,并使用另一个寄存器来保存计算结果。

下面是具体的汇编代码:```MOV AX, 0x1000 ; 将地址0x1000存入寄存器AXMOV BX, 0 ; 初始化计数器BX为0MOV CX, 1 ; 初始化计数器CX为1MOV DX, 0 ; 初始化计算结果DX为0LOOP_START:MOV [AX+BX], DX ; 将计算结果存入内存空间ADD DX, CX ; 计算下一个数XCHG DX, CX ; 交换计算结果和前一个数INC BX ; 计数器加1CMP BX, 10 ; 判断是否计算完成JL LOOP_START ; 如果计数器小于10,继续循环```以上是一个简单的汇编程序实例,通过循环计算并保存斐波那契数列的前10个数字。

51单片机汇编语言及C语言经典实例解析

51单片机汇编语言及C语言经典实例解析

51单片机汇编语言及C语言经典实例实验及课程设计一、闪烁灯如图1 所示为一简单单片机系统原理图:在P1.0 端口上接一个发光二极管L1,使L1 在不停地一亮一灭,一亮一灭的时间间隔为0.2 秒。

延时程序的设计方法,作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要求的闪烁时间间隔为0.2 秒,相对于微秒来说,相差太大,所以我们在执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程序是如何设计呢?下面具体介绍其原理:如图4.1.1 所示的石英晶体为12MHz,因此,1 个机器周期为 1 微秒,机器周期微秒如图 1 所示,当P1.0 端口输出高电平,即P1.0=1 时,根据发光二极管的单向导电性可知,这时发光二极管L1 熄灭;当P1.0 端口输出低电平,即P1.0=0 时,发光二极管L1 亮;我们可以使用SETB P1.0 指令使P1.0端口输出高电平,使用CLR P1.0 指令使P1.0 端口输出低电平。

C 语言源程序#include <AT89X51.H>sbit L1=P1^0;void delay02s(void) //延时0.2 秒子程序{unsigned char i,j,k;for(i=20;i>0;i--)for(j=20;j>0;j--)for(k=248;k>0;k--);}void main(void){while(1){L1=0;delay02s();L1=1;delay02s();}汇编源程序ORG 0START: CLR P1.0LCALL DELAYSETB P1.0LCALL DELAYLJMP START DELAY: MOV R5,#20 ;延时子程序,延时0.2 秒D1: MOV R6,#20D2: MOV R7,#248DJNZ R7,$DJNZ R6,D2DJNZ R5,D1RETEND图2 程序设计流程图图1 单片机原理图二、多路开关状态指示如图 3 所示,AT89S51 单片机的 P1.0-P1.3 接四个发光二极管 L1-L4,P1.4-P1.7 接了四个开关 K1-K4,编程将开关的状态反映到发光二极管上。

汇编语言程序设计实例分析

汇编语言程序设计实例分析
MOV DS,AX
MOV AL,TAB MOV BX,OFFSET TAB MOV CL,9 LL: INC BX CMP AL,[BX] JAE TT XCHG AL,[BX] TT: DEC CL JNZ LL MOV MAX,AL MOV AH,4CH INT 21H CODE ENDS END START
例3:设计一个程序,统计内存W单元保 存的无符号字数据中有多少个二进制 “1”,结果送内存N单元保存
分析:要统计内存W单元保存的无符号字数 据中有多少个二进制“1”,可将该数据送至 寄存器AX中,通过移位指令将AX中的每一 位依次移入进位位CF中,若CF=1则计数器 CL的值加1。 这样就可以统计出址加1 ;两数比较 ;大于等于转 ;交换数据位置 ;计数器减1 ;非0转 ;保存最大数
例7:从键盘输入3-9之间的数字,用 “*”号组成三角形图案
例如:输入数字7,屏幕上显示出以下图案: ******* ****** ***** **** *** ** * 可采用双重循环程序,外循环控制行数,内循环 控制列数。
CODE SEGMENT ASSUME CS:CODE START:MOV AH,01H INT 21H CMP AL,33H JB START CMP AL,39H JA START SUB AL,30H MOV CL,AL MOV CH,0 MOV DL,0DH MOV AH,02H INT 21H MOV DL,0AH INT 21H
思考:在本例的基础上,若要在屏幕上 显示出以下图案,应该如何设计程序?
* ** *** **** ***** ****** ******* ********* 或者: * * *
*
* * ************

汇编语言程序举例ppt课件

汇编语言程序举例ppt课件
S x x x (Q3) × S y y y (Q3) S S z z z z z z (Q6格式)
即两个带符号数相乘,得到的乘积带有2个符号位 ,造成错误的结果。
同样,对于两个十六位数相乘,乘积只有30位, 在最高的两位也是符号位,同样会造成错误的结果.
解决冗余符号的办法是:在程序中设定状态寄存器 ST1中的FRCT(小数方式)位1,在乘法器将结果传送 至累加器时就能自动地左移1位,累加器中的结果为: S zzzzzz0 ( Q7 格 式 ) , 即 11101000 ( -0.1875=24/27←-24=(11101000)补),自动地消去了两个带 符号数相乘时产生的冗余符号位。所以在小数乘法编 程时,应当事先设置FRCT位:
汇编语言编程举例
第一节 汇编语言编程的基本方法 第二节 DSP的浮点运算方法 第三节 DSP在信号发生器上的应用 第四节 用DSP实现FIR滤波器 第五节 用DSP实现IIR滤波器
第一节 汇编语言编程的基本方法
1.堆栈的使用
1.压入数据时,堆栈从高地址向低地址 增长。 2.压栈时指针先减,SP-1,再压入数据; 3.出栈时,先弹出数据后,再SP+1。 4.如要用堆栈,必须先设置,后使用。
(2)数据存储器→数据存储器
例: 将数据存储器中的数组x[10]复制到数组y[10]。
.title “cjy1.asm” ;为汇编源程序取名
.mmregs
;定义存储器映象寄存器
STACK .usect “STACK”,30H;设置堆栈
.bss x,10 ;为数组x分配10个存储单元
.bss y,10 ;为数组y分配10个存储单元
为:
MSB(最高位)

LSB(最低位)

汇编教程汇编语言编程实例

汇编教程汇编语言编程实例

汇编语言编程实例一这一章,我们要把我们已学的知识集合起来。

具体来讲,我们来写一个使用ODBC APIs的程序.为简单起见,这个程序中我使用Microsoft的Access数据库(Microso ft Access 97) .注意:如果你使用的windows.inc 是1.18及其以下版本,在开始编译之前要修改其中的一个小bug.在windows.inc中查找 "SQL_NULL_HANDLE",将得到下面这行:SQL_NULL_HANDLE equ 0L将0后面的"L"删除,象这样:SQL_NULL_HANDLE equ 0这个程序是一个基于对话框的程序,有一个简单的菜单.当用户选择"connect"时,它将试图连接test.mdb数据库,如果连接成功,将显示由ODBC驱动程序返回的完整连接字符串.接下来,用户可选择"View All Records"命令,程序会使用listview control来显示数据库中的所有数据.用户还可以选择"Query"命令来查询特定的记录.例子程序将会显示一个小对话框提示用户输入想找的人名.当用户按下OK钮或回车键,程序将执行一个查询来查找符合条件的记录.当用户完成对数据库的操作时,可以选择"disconnect"命令与数据库断开连接.现在看一下源程序:.386.model flat,stdcallinclude \masm32\include\windows.incinclude \masm32\include\kernel32.incinclude \masm32\include\odbc32.incinclude \masm32\include\comctl32.incinclude \masm32\include\user32.incincludelib \masm32\lib\odbc32.libincludelib \masm32\lib\comctl32.libincludelib \masm32\lib\kernel32.libincludelib \masm32\lib\user32.libIDD_MAINDLG equ 101IDR_MAINMENU equ 102IDC_DATALIST equ 1000IDM_CONNECT equ 40001IDM_DISCONNECT equ 40002IDM_QUERY equ 40003IDC_NAME equ 1000IDC_OK equ 1001IDC_CANCEL equ 1002IDM_CUSTOMQUERY equ 40004IDD_QUERYDLG equ 102DlgProc proto hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORDQueryProc proto hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD SwitchMenuState proto :DWORDODBCConnect proto :DWORDODBCDisconnect proto :DWORDRunQuery proto :DWORD.data?hInstance dd ?hEnv dd ?hConn dd ?hStmt dd ?Conn db 256 dup(?)StrLen dd ?hMenu dd ? ; 主菜单句柄hList dd ? ; listview control句柄TheName db 26 dup(?)TheSurname db 26 dup(?)TelNo db 21 dup(?)NameLength dd ?SurnameLength dd ?TelNoLength dd ?SearchName db 26 dup(?)ProgPath db 256 dup(?)ConnectString db 1024 dup(?).dataSQLStatement db "select * from main",0WhereStatement db " where name=?",0strConnect db "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=",0 DBName db "test.mdb",0ConnectCaption db "Complete Connection String",0Disconnect db "Disconnect successful",0AppName db "ODBC Test",0AllocEnvFail db "Environment handle allocation failed",0 AllocConnFail db "Connection handle allocation failed",0 SetAttrFail db "Cannot set desired ODBC version",0NoData db "You must type the name in the edit box",0ExecuteFail db "Execution of SQL statement failed",0ConnFail db "Connection attempt failed",0AllocStmtFail db "Statement handle allocation failed",0Heading1 db "Name",0Heading2 db "Surname",0Heading3 db "Telephone No.",0.codestart:invoke GetModuleHandle, NULLmov hInstance,eaxcall GetProgramPathinvoke DialogBoxParam, hInstance, IDD_MAINDLG,0,addr DlgProc,0invoke ExitProcess,eaxinvoke InitCommonControlsDlgProc proc hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD.if uMsg==WM_INITDIALOGinvoke GetMenu, hDlgmov hMenu,eaxinvoke GetDlgItem, hDlg, IDC_DATALISTmov hList,eaxcall InsertColumn.elseif uMsg==WM_CLOSEinvoke GetMenuState, hMenu, IDM_CONNECT,MF_BYCOMMAND.if eax==MF_GRAYEDinvoke ODBCDisconnect, hDlg.endifinvoke EndDialog,hDlg, 0.elseif uMsg==WM_COMMAND.if lParam==0mov eax,wParam.if ax==IDM_CONNECTinvoke ODBCConnect,hDlg.elseif ax==IDM_DISCONNECTinvoke ODBCDisconnect,hDlg.elseif ax==IDM_QUERYinvoke RunQuery,hDlg.elseif ax==IDM_CUSTOMQUERYinvoke DialogBoxParam, hInstance, IDD_QUERYDLG,hDlg, addr QueryProc, 0 .endif.endif.elsemov eax,FALSEret.endifmov eax,TRUEretDlgProc endpGetProgramPath procinvoke GetModuleFileName, NULL,addr ProgPath,sizeof ProgPathstdmov edi,offset ProgPathadd edi,sizeof ProgPath-1mov al,"\"mov ecx,sizeof ProgPathrepne scasbcldmov byte ptr [edi+2],0retGetProgramPath endpSwitchMenuState proc Flag:DWORD.if Flag==TRUEinvoke EnableMenuItem, hMenu, IDM_CONNECT, MF_GRAYEDinvoke EnableMenuItem, hMenu, IDM_DISCONNECT, MF_ENABLEDinvoke EnableMenuItem, hMenu, IDM_QUERY, MF_ENABLEDinvoke EnableMenuItem, hMenu, IDM_CUSTOMQUERY, MF_ENABLED.elseinvoke EnableMenuItem, hMenu, IDM_CONNECT, MF_ENABLEDinvoke EnableMenuItem, hMenu, IDM_DISCONNECT, MF_GRAYEDinvoke EnableMenuItem, hMenu, IDM_QUERY, MF_GRAYEDinvoke EnableMenuItem, hMenu, IDM_CUSTOMQUERY, MF_GRAYED.endifretSwitchMenuState endpODBCConnect proc hDlg:DWORDinvoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_NULL_HANDLE, addr hEnv.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOinvoke SQLSetEnvAttr, hEnv,SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3,0.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOinvoke SQLAllocHandle, SQL_HANDLE_DBC, hEnv, addr hConn.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOinvoke lstrcpy,addr ConnectString,addr strConnectinvoke lstrcat,addr ConnectString, addr ProgPathinvoke lstrcat, addr ConnectString,addr DBNameinvoke SQLDriverConnect, hConn, hDlg, addr ConnectString, sizeof ConnectString, addr Conn, sizeof Conn,addr StrLen, SQL_DRIVER_COMPLETE.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOinvoke SwitchMenuState,TRUEinvoke MessageBox,hDlg, addr Conn,addr ConnectCaption,MB_OK+MB_ICONINFORMATION .elseinvoke SQLFreeHandle, SQL_HANDLE_DBC, hConninvoke SQLFreeHandle, SQL_HANDLE_ENV, hEnvinvoke MessageBox, hDlg, addr ConnFail, addr AppName, MB_OK+MB_ICONERROR.endif.elseinvoke SQLFreeHandle, SQL_HANDLE_ENV, hEnvinvoke MessageBox, hDlg, addr AllocConnFail, addr AppName, MB_OK+MB_ICONERROR .endif.elseinvoke SQLFreeHandle, SQL_HANDLE_ENV, hEnvinvoke MessageBox, hDlg, addr SetAttrFail, addr AppName, MB_OK+MB_ICONERROR.endif.elseinvoke MessageBox, hDlg, addr AllocEnvFail, addr AppName, MB_OK+MB_ICONERROR .endifretODBCConnect endpODBCDisconnect proc hDlg:DWORDinvoke SQLDisconnect, hConninvoke SQLFreeHandle, SQL_HANDLE_DBC, hConninvoke SQLFreeHandle, SQL_HANDLE_ENV, hEnvinvoke SwitchMenuState, FALSEinvoke ShowWindow,hList, SW_HIDEinvoke MessageBox,hDlg,addr Disconnect, addr AppName,MB_OK+MB_ICONINFORMATION retODBCDisconnect endpInsertColumn procLOCAL lvc:LV_COLUMNmov lvc.imask,LVCF_TEXT+LVCF_WIDTHmov lvc.pszText,offset Heading1mov lvc.lx,150invoke SendMessage,hList, LVM_INSERTCOLUMN,0,addr lvcmov lvc.pszText,offset Heading2invoke SendMessage,hList, LVM_INSERTCOLUMN, 1 ,addr lvcmov lvc.pszText,offset Heading3invoke SendMessage,hList, LVM_INSERTCOLUMN, 3 ,addr lvcretInsertColumn endpFillData procLOCAL lvi:LV_ITEMLOCAL row:DWORDinvoke SQLBindCol, hStmt,1,SQL_C_CHAR, addr TheName, sizeof TheName,addr NameLe ngthinvoke SQLBindCol, hStmt,2,SQL_C_CHAR, addr TheSurname, sizeof TheSurname,addr SurnameLengthinvoke SQLBindCol, hStmt,3,SQL_C_CHAR, addr TelNo, sizeof TelNo,addr TelNoLengt hmov row,0.while TRUEmov byte ptr ds:[TheName],0mov byte ptr ds:[TheSurname],0mov byte ptr ds:[TelNo],0invoke SQLFetch, hStmt.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOmov lvi.imask,LVIF_TEXT+LVIF_PARAMpush rowpop lvi.iItemmov lvi.iSubItem,0mov lvi.pszText, offset TheNamepush rowpop lvi.lParaminvoke SendMessage,hList, LVM_INSERTITEM,0, addr lvimov lvi.imask,LVIF_TEXTinc lvi.iSubItemmov lvi.pszText,offset TheSurnameinvoke SendMessage,hList,LVM_SETITEM, 0,addr lviinc lvi.iSubItemmov lvi.pszText,offset TelNoinvoke SendMessage,hList,LVM_SETITEM, 0,addr lviinc row.else.break.endif.endwretFillData endpRunQuery proc hDlg:DWORDinvoke ShowWindow, hList, SW_SHOWinvoke SendMessage, hList, LVM_DELETEALLITEMS,0,0invoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOinvoke SQLExecDirect, hStmt, addr SQLStatement, sizeof SQLStatement.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOinvoke FillData.elseinvoke ShowWindow, hList, SW_HIDEinvoke MessageBox,hDlg,addr ExecuteFail, addr AppName, MB_OK+MB_ICONERROR .endifinvoke SQLCloseCursor, hStmtinvoke SQLFreeHandle, SQL_HANDLE_STMT, hStmt.elseinvoke ShowWindow, hList, SW_HIDEinvoke MessageBox,hDlg,addr AllocStmtFail, addr AppName, MB_OK+MB_ICONERROR .endifretRunQuery endpQueryProc proc hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD.if uMsg==WM_CLOSEinvoke SQLFreeHandle, SQL_HANDLE_STMT, hStmtinvoke EndDialog, hDlg,0.elseif uMsg==WM_INITDIALOGinvoke ShowWindow, hList, SW_SHOWinvoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOinvoke lstrcpy, addr Conn, addr SQLStatementinvoke lstrcat, addr Conn, addr WhereStatementinvoke SQLBindParameter,hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,25,0, a ddr SearchName,25,addr StrLeninvoke SQLPrepare, hStmt, addr Conn, sizeof Conn.elseinvoke ShowWindow, hList, SW_HIDEinvoke MessageBox,hDlg,addr AllocStmtFail, addr AppName, MB_OK+MB_ICONERROR invoke EndDialog, hDlg,0.endif.elseif uMsg==WM_COMMANDmov eax, wParamshr eax,16.if ax==BN_CLICKEDmov eax,wParam.if ax==IDC_OKinvoke GetDlgItemText, hDlg, IDC_NAME, addr SearchName, 25.if ax==0invoke MessageBox, hDlg,addr NoData, addr AppName, MB_OK+MB_ICONERRORinvoke GetDlgItem, hDlg, IDC_NAMEinvoke SetFocus, eax.elseinvoke lstrlen,addr SearchNamemov StrLen,eaxinvoke SendMessage, hList, LVM_DELETEALLITEMS,0,0invoke SQLExecute, hStmtinvoke FillDatainvoke SQLCloseCursor, hStmt.endif.elseinvoke SQLFreeHandle, SQL_HANDLE_STMT, hStmtinvoke EndDialog, hDlg,0.endif.endif.elsemov eax,FALSEret.endifmov eax,TRUEretQueryProc endpend start分析start:invoke GetModuleHandle, NULLmov hInstance,eaxcall GetProgramPath当程序开始时,将获得实例句柄并获得所在路径.默认情况下数据库 test.mdb应与程序处于同一文件夹.GetProgramPath procinvoke GetModuleFileName, NULL,addr ProgPath,sizeof ProgPathstdmov edi,offset ProgPathadd edi,sizeof ProgPath-1mov al,"\"mov ecx,sizeof ProgPathrepne scasbcldmov byte ptr [edi+2],0retGetProgramPath endpGetProgramPath调用GetModuleFileName来获得程序的全路径名.接着在路径中查找最后一个"\"符",通过将文件名的第一个字符置为0获得(truncate)" 文件名. 因此我们在Pr ogPath中获得了程序的路径名.然后程序将用DialogBoxParam显示主对话框.当主对话框第一次被载入时,它将获得菜单句柄和listview control句柄.接下来在listview control中插入三列(因为我们已经知道结果集将包含三列.因为是我们先建的表.)现在,它就等待用户的动作了.如果用户在菜单中选择"connect",将会调用ODBCConnec t函数.ODBCConnect proc hDlg:DWORDinvoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_NULL_HANDLE, addr hEnv.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO它做的第一件事是调用SQLAllocHandle来分配一个环境句柄.invoke SQLSetEnvAttr, hEnv,SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3,0.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO获得环境句柄后,程序调用SQLSetEnvAttr来表示将要使用ODBC 3.x的语法.invoke SQLAllocHandle, SQL_HANDLE_DBC, hEnv, addr hConn.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO如果一切顺利,程序将通过调用SQLAllocHandle获得连接句柄来实现连接.invoke lstrcpy,addr ConnectString,addr strConnectinvoke lstrcat,addr ConnectString, addr ProgPathinvoke lstrcat, addr ConnectString,addr DBName接着填写连接字符串.完整的连接字符串将被用在ConnectionStringinvoke SQLDriverConnect, hConn, hDlg, addr ConnectString, sizeof ConnectString, addr Conn, sizeof Conn,addr StrLen, SQL_DRIVER_COMPLETE.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOinvoke SwitchMenuState,TRUEinvoke MessageBox,hDlg, addr Conn,addr ConnectCaption,MB_OK+MB_ICONINFORMATION当连接字符串完成,程序将调用SQLDriverConnect来通过MS Access ODBC 驱动程序连接test.mdb数据库.如果文件test.mdb不存在,ODBC driver将提示用户输入该文件的位置,因为我们已经设定了SQL_DRIVER_COMPLETE标志.当SQLDriverConnect成功返回时, Conn 被填入由ODBC驱动程序创建的完整连接字符串.我们通过一个message box来将其显示给用户. SwitchMenuState是一个单纯切换菜单选项可用的函数.现在,到数据库的连接已经建立并被打开,并一直保持打开状态直到用户选择关闭.当用户选择了"View All Records"命令, 对话框过程将调用RunQuery.函数RunQuery proc hDlg:DWORDinvoke ShowWindow, hList, SW_SHOWinvoke SendMessage, hList, LVM_DELETEALLITEMS,0,0由于listview control在创建时是不可见的,现在我们把它显示出来.还有要把其中的所有元素(如果有的话)删掉.invoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO接下来,程序将获得一个语句句柄.invoke SQLExecDirect, hStmt, addr SQLStatement, sizeof SQLStatement.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO通过 SQLExecDirect执行已准备好的SQL语句.我这里选择SQLExecDirect 的原因是只须执行一次.invoke FillData执行SQL语句后,将返回一个结果集.我们使用 FillData函数来从结果集中解出数据并将其放入listview control中.FillData procLOCAL lvi:LV_ITEMLOCAL row:DWORDinvoke SQLBindCol, hStmt,1,SQL_C_CHAR, addr TheName, sizeof TheName,addr NameLe ngthinvoke SQLBindCol, hStmt,2,SQL_C_CHAR, addr TheSurname, sizeof TheSurname,addr SurnameLengthinvoke SQLBindCol, hStmt,3,SQL_C_CHAR, addr TelNo, sizeof TelNo,addr TelNoLengt h现在,结果集被返回.我们要绑定结果集的所有三列到我们提供的缓冲区中.这是调用S QLBindCol来实现的.注意我们要对每一列分别调用.并且我们并不需要绑定所有的列:只要绑定要获得数据的列就行了.mov row,0.while TRUEmov byte ptr ds:[TheName],0mov byte ptr ds:[TheSurname],0mov byte ptr ds:[TelNo],0当列中没有数据时,我们初始化缓冲区为NULLs.更好的方法是用SQLBindCol指定的变量中数据的长度.在我们的例子中,我们可以检查NameLength, SurnameLength和TelNoLeng th中的值的确切长度.invoke SQLFetch, hStmt.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOmov lvi.imask,LVIF_TEXT+LVIF_PARAMpush rowpop lvi.iItemmov lvi.iSubItem,0mov lvi.pszText, offset TheNamepush rowpop lvi.lParaminvoke SendMessage,hList, LVM_INSERTITEM,0, addr lvi其它都很简单了.调用SQLFetch 来获得结果集的一行,并将其存入listview control 的缓冲区中.当没有更多的行供检索时(已到达文件尾), SQLFetch返回SQL_NO_DATA并且程序跳出循环.invoke SQLCloseCursor, hStmtinvoke SQLFreeHandle, SQL_HANDLE_STMT, hStmt当完成对结果集的操作时,调用SQLCloseCursor关闭结果集并调用SQLFreeHandle释放语句句柄.当用户选择"Query"命令,程序显示另一个对话框供用户输入要查询的名字..elseif uMsg==WM_INITDIALOGinvoke ShowWindow, hList, SW_SHOWinvoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFOinvoke lstrcpy, addr Conn, addr SQLStatementinvoke lstrcat, addr Conn, addr WhereStatementinvoke SQLBindParameter,hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,25,0, a ddr SearchName,25,addr StrLeninvoke SQLPrepare, hStmt, addr Conn, sizeof Conn对话框做的第一件事是显示listview control.接下来分配一个语句句柄以创建SQL语句.这个SQL语句有一个"where"子句及一个参数标志符"?". 完整的SQL语句是:select * from main where name=?接着程序调用SQLBindParameter 来建立参数标志符与缓冲区SearchName的连接,这样当SQL语句被执行时,ODBC驱动程序就可从SearchName中获得需要的字符串.接下来,程序调用SQLPrepare来编译SQL语句. 这样我们只要准备/编译SQL语句一次就可多次使用.因为SQL语句已被编译过,接下来的执行过程会快一些..if ax==IDC_OKinvoke GetDlgItemText, hDlg, IDC_NAME, addr SearchName, 25.if ax==0invoke MessageBox, hDlg,addr NoData, addr AppName, MB_OK+MB_ICONERRORinvoke GetDlgItem, hDlg, IDC_NAMEinvoke SetFocus, eax.else当用户在编辑框(edit control)中填入了一些名字并按下回车键, 程序将获得编辑框中的文本并检查是否是空字符串.如果是,则显示一个message box并将键盘焦点设在编辑框上,提示用户输入名字.invoke lstrlen,addr SearchNamemov StrLen,eaxinvoke SendMessage, hList, LVM_DELETEALLITEMS,0,0invoke SQLExecute, hStmtinvoke FillDatainvoke SQLCloseCursor, hStmt如果编辑框中已有字符串,程序会获得它的长度并将其放入StrLen中供ODBC驱动程序使用(记住我们已将StrLen的地址传送给了SQLBindParameter). 接下来程序使用获得的语句句柄调用SQLExecute执行已准备好的SQL语句.当 SQLExecute返回时,程序调用FillDa ta在listview control显示结果.因为我们不会再用到结果集,调用SQLCloseCursor来关闭它.。

第二章--第四节--汇编语言程序设计方法(二)

第二章--第四节--汇编语言程序设计方法(二)
VCC GND 31 19 C2 3 0p F Y1 6 . 00 0M HZ 18 E A/VP X1 AT 8 9C5 1 P0. 0 P0. 1 P0. 2 P0. 3 P0. 4 P0. 5 P0. 6 P0. 7 P2. 0 P2. 1 P2. 2 P2. 3 P2. 4 P2. 5 P2. 6 P2. 7 RD WR PSE N AL E /P T XD RXD 39 38 37 36 35 34 33 32 21 22 23 24 25 26 27 28 17 16 29 30 11 10 VCC R9 4 . 7K GND SW
A+30HA A(22H) 结束
R0
0010 0000
END
BCD码十进制转换成二进制
例:假如在内部RAM40H单元中存储有一个压缩BCD编码 的两位十进制数,设计一段程序把这个数转换成二进制数 并存入41H单元中。 解题思路: (40H) 16 商为二进制的高四位
余数
余为二进制的低四位
将高四位乘以0AH,再加上低四位即可。
数据排序程序 例:将片内RAM中20H-27H中的数据按照从小到大的顺序重新排列。 解题思路:见下图
RAM地址 原始数据
20H 66H
21H 11H
22H 10H
23H 34H
24H 67H
25H 01H
26H 89H
27H A0H
1
2 3 4 5 6 7
01H
01H 01H 01H 01H 01H 01H
11H
10H 10H 10H 10H 10H 10H
10H
11H 11H 11H 11H 11H 11H
34H
34H 34H 34H 34H 34H 34H

【Selected】程序汇编实验举例及总结.doc

【Selected】程序汇编实验举例及总结.doc

一、实验内容1.在屏幕上显示一个字符的源程序:DATASSEGMENTSTRINGDB'HELLO!','$'ORG100HDATASENDSCODESSEGMENTASSUMECS:CODES,DS:DATASSTART:MOVAG,DATASMOVDS,AGLEADG,STRINGMOVAH,09HINT21HMOVAH,4CHINT21HCODESENDSENDSTART2.编写一个程序,实现字符串的复制功能,并且将复制的字符串显示出来DATASSEGMENTSTRING_ADB'ICHLIEBEDICH','$'COUNTEQU$-OFFSETSTRING_ASTACASSEGMENTSTRING_BDBCOUNTDUP(?) STACASENDSCODESSEGMENTASSUMECS:CODES,DS:DATAS,SS:STACAS START:MOVAG,DATASMOVDS,AGMOVAG,STACASMOVES,AGLEASI,STRING_ALEADI,STRING_BMOVCG,COUNTSTDREPMOVSBLEADG,STRING_BMOVAH,9INT21HMOVAH,4CHINT21HMOVAH,4CHINT21HCODESENDS3、利用中断调用,在屏幕上显示1—9之间随机数。

中断号86HDATASSEGMENTCLADB13,10,'WEAREGOINGTOPRODUCEANUMBERATRANDOM:$:' INFONDB0DH,0AH,'THEPROGRAMRUNSGOOD$'DATASENDSSTACASSEGMENTSTACADB200DUP(0)STACASENDSCODESSEGMENTASSUMEDS:DATAS,SS:STACAS,CS:CODESSTART:MOVAG,DATASMOVDS,AGLEADG,CLAMOVAH,9INT21HMOVAG,0MOVES,AG;MOVBG,86HG4CLIMOVWORDPTRES:[BG],OFFSETRANMOVWORDPTRES:[BG+2],SEGRANSTIINT86H MOVAH,02H INT21H LEADG,INFON MOVAH,9INT21H MOVAG,4C00H INT21H RANPROC PUSHCG PUSHDG MOVAH,0INT1AH MOVAG,DG GORDG,DG MOVBG,10 DIVBG ADDDL,30H MOVAH,02H INT21H POPDG POPCGIRETRANENDPCODESENDSENDSTART4.复制字符串,并倒序输出DATASSEGMENTSTRING_ADB'stillhere',13,10,'$'STRING_LDB'$'DATASENDSSTACASSEGMENTSTRING_BDB100DUP(?)STACASENDSCODESSEGMENTASSUMECS:CODES,DS:DATAS,SS:STACASSTART:MOVAG,DATASMOVDS,AGMOVAG,STACASMOVSS,AGLEASI,STRING_LMOVAG,SILEASI,STRING_ALEADI,STRING_BSUBAG,SISUBAG,3 MOVCG,AG MOVBG,AG STD REPMOVSB LEADG,STRING_B MOVAH,9INT21H MOVDL,13 MOVAH,2INT21H MOVDL,10 MOVAH,2INT21H LEASI,STRING_B MOVCG,BG ADDSI,BG DECSIS:MOVDL,[SI] MOVAH,2INT21HDECSILOOPSMOVAH,004CHINT21HCODESENDSENDSTART5、显示比较两个数的大小DATASEGMENTADB33HBDB87HDATAENDSSTACASEGMENTDW128DUP(?)STACAENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACASTART:MOVAG,DATAMOVDS,AGMOVAL,'A'CMPB,ALJABGAMOVDL,'A'MOVBL,'B'JMPDISPBGA:MOVDL,'B'MOVBL,'A'DISP:MOVAH,2INT21HMOVDL,'>'INT21HMOVDL,BLINT21HMOVAH,4CHINT21HCODEENDSENDSTART6、键盘输入10个学生的成绩,编写一个程序统计60-69分,70-79分,80-89分,90-99分及100分的人数,分别存放在Score6,Score7,Score8,Score9和Score10单元中。

第4章汇编语言程序设计及编程实例1

第4章汇编语言程序设计及编程实例1




一、分析问题




对需要解决的问题进行分析,以求对问题由正确的 理解。如, 解决问题的任务是什么? 工作过程? 现有的条件,已知数据,对运算的精度和速度方面 的要求? 设计的硬件结构是否方便编程?
二、确定算法


算法是如何将实际问题转化成程序模块来处理。 在编程以前,先要对几种不同的算法进行分析、比 较,找出最适宜的算法
§4.2 汇编语言源程序的编辑和汇编
§4.2.1 源程序编辑
§4.2.2 源程序的汇编
§4.2.3 伪指令
§4.2.1 源程序编辑

在微型计算机上,借助编辑软件,编写或修 改汇编语言源程序。如行编辑或屏幕编辑软
件。
§4.2.2 源程序的汇编

汇编:将汇编语言源程序转换为机器码表示的目标 程序的过程。对单片机有: 一、手工汇编
标号



标号是用户定义的符号地址。 一条指令的标号是该条指令的符号名字,标号的值是汇编这 条指令时指令的地址。 标号由以英文字母开始的1~8个字母或数字组成,以冒号 “:”结尾。 标号可以由赋值伪指令赋值,如果没有赋值,汇编程序把存 放该指令目标码第一字节的存储单元的地址赋给该标号,所 以,标号又叫指令标号。
操作码


操作码是必不可少的。 它用一组字母符号表示指令的操作码。在89C51中, 由89C51的指令助记符组成。
操作数




汇编语言指令可能要求或不要求操作数,所以这一字段可能有也可能没 有。 若有两个操作数,操作数之间用逗号“,”分开。 操作数包括的内容有: (1)工作寄存器:由PSW.3和PSW.4规定的当前工作寄存器区中的 R0~R7。 (2)特殊功能寄存器:21个SFR的名字。 (3)标号名:赋值标号—由汇编指令EQU等赋值的标号;指令标号— 指令标号指示的指令的第一字节地址是该标号的值。 (4)常数:可用二进制(B)、十进制、十六进制(H),若常数以字 符开头,前面加0。 (5)$:用来表示程序计数器的当前值。 (6)表达式:汇编时,计算出表达式的值填入目标码。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

;地址 0405h
.bss z3_h,1
;地址 0406h
.bss z3_l,1
;地址 0407h
.bss z4,1
;地址 0408h
v1
.set 014H
;20---x1
v2
.set 036H
;54---y1
v1
.set 04000H
;0.5---x2
v2
.set 0b548H
;-> z1
LD
x1,A
;x1->A
SUB
y1,A
;A+y1 ->A
STL
A,z2
;保存 AL -> z1
;********text MPY(整数)*******
RSBX
FRCT
;FRCT=0 整数乘法
LD
x1,T
;x1 ->T
MPY
y1,A
;x1*y1 ->A (结果32位)
STH
A,z3_h
RPT #39
;x[20]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
MVPD TBL,*AR1+
STM #x,AR2
;将数据存储器x[20]到y[20]
STM #y,AR3
RPT #19
MVDD *AR2+,*AR3+
STM #a,AR1
;数据存储器a[20]写入程序存储器PROM
Z-1 h(2)
Z-1 h(N-2)
图7-10 横截型FIR数字滤波器的结构图
h(N-1) y(n)
图7-12 FIR滤波器循环缓冲区存储器图
*****采用循环缓冲区法编写的FIR数字滤波器程序*****
.mmrege
.global
start
.def
start, _c_int00
KS
.set
256
FRCT #h,AR2 #4 table,*AR2+ #y,AR5 #x+4,AR1 #h+4,AR2 #4,AR0 #x1,AR3 #x,AR4 #5,BRC loop-1 PA0,*AR3 *AR3,*AR4 *AR1-,T *AR2-,A *AR1*AR2-,A *AR1*AR2-,A *AR1*AR2-,A *AR1+0 *AR2+0,A A,*AR5 *AR5,PA1
MVPD COEF_FIR,*COEF_P+
STM #-1,AR0
;地址步进-1
STM
#DATABUF,DATA_P ;数据缓冲区清0
RPTZ A,#N-1
STL
;乘法结果高16位在z3_h
STL
A,z3_l;乘法结果低16位在z3_l
**************test MPY(小数)*********
****** 0.5x(-0.58374)=-0.29187(0xdaa4)
ST
#v3,x2
ST
#v4,y2
SSBX
FRCT
;准备小数乘法,FRCT=1
LD
a1=0.1,a2=0.2,a3=-0.3,a4=0.4,x1=0.8,x2=0.6,x3=-0.4,x4=-0.2
Table:
.title “chef.asm” .mmregs .def start,_c_int00 .bss x,4 .bss a,4 .bss y,1 .data .word 1*32768/10 .word 2*32768/10 .word -3*32768/10 .word 4*32768/10 .word 8*32768/10 .word 6*32768/10 .word -4*32768/10 .word -2*32768/10
;该指令为单字指令
WAIT: NOP
B
WAIT
.end
建立链接命令文件
MEMORY
{ PAGE 0: RAM: origin = 1000h,length = 800h
RAM1: origin = 2000h,length = 300h
PAGE 1: DARAM1: origin = 0100h,length = 100h
;输入的样本数
N
.set
17
;FIR滤波器阶数
COEF
.sect
“COEF_FIR” ;FIR滤波器系数
.word 1,158,264,-290,-1406,-951,3187,9287,12272
.word 9287,3187,-951,-1406,-290,264,158,0
.data
INPUT
.text
.asg
AR4,DATA_P
.asg
AR5,COEF_P
.asg
AR6,INBUF_P
.asg
AR7,OUTBUF_P
_c_int00: B
start
start:
SSBX FRCT
;小数乘法,FRCT=1
STM
#COEFTAB,COEF_P ;FIR系数从程序区搬移到数据区
RPT #N-1
.copy
“firin.inc”
;输入数据在数据区0x2400
OUTPUT .space
1024
;输入数据在数据区0x2500
COEFTAB .usect
“FIR_COEF”,N
DATABUF .usect
“FIR_BFR”,N
BOS
.usect
“STACK”,0Fh
TOS
.usect
“STACK”,1
RPT #4
;重复执行的次数为5
STL A,*AR1+
****对数组x[5]中的元素加1****
LD #1,16,B
STM #4,BRC
STM #x,AR4
RPTB next-1
ADD *AR4,16,B,A
STH A,*AR4+
next:
LD #0,B
.end
[例7-3] 1.实现数组
a[20]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}
0213H)
.def _c_int00 .data
TBL:
.word 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19
PROM
.word 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 .usect “PROM”,20
PAGE 1: OTHER: origin = 0100h,length = 100h
}
SECYIONS
{
.text :> ROM
PAGE 0
.data :> ROM
PAGE 0
.bss :> OTHER PAGE 1
.stack :> OTHER PAGE 1
}
4
[例7-5]用双操作数编程计算 y ai xi i 1
LD
#PROM,A
STM #19,AR3
LOOPP: WRITA *AR1+
ADD #1,A,A
BANZ LOOPP,*AR3-
LD
#PROM-1,A ;程序存储器PROM存入数据存储器DATA
STM #DATA,AR1
STM #19,BRC
RPTB LOOP2
ADD #1,A,A
LOOP2: READA *AR1+
.word
4*32768/10
.word
-3*32768/10
.word
2*32768/10
_c_int00: FIR1: loop:
.text SSBX STM RPT MVPD STM STM STM STM STM STM STM RPTB PORTR MVDD LD MPY LTD MAC LTD MAC LTD MAC LTD MAC STH PORTW NOP .end
.bss a,20
.bss x,20
DATA
.bss y,20 .usect “DATA”,20
.text
_c_int00: B start
NOP
NOP
start: STM #a,AR1
;a[20]={0,1,2,3,4,5,6,7,8,9,10,
;11,12,13,14,15,16,17,18,19}
数据 存储器
x(n) x(n-1)
x(n-2) x(n-3)
数据 存储器
数据 存储器
x(n+1) PORTR x(n) x(n-1)
x(n-2)
x(n+2) x(n+1)
x(n) x(n-1)
x(n-4)
x(n-3)
x(n-2)
*Arx-
x(n-5) *Arx- x(n-4) *Arx- x(n-3)
.title "FIR.ASM"
;用线性缓冲区和间接寻址方法实现FIR滤波器
.mmregs
.def
_c_int00
x
.usect
"x",5
h
.usect
"h",5
.bss
x1,1
.bss
y,1
PA0
.set
0
PA1
.set
1
.data
table:
.word
2*32768/10
.word
-3*32768/10
.text
_c_int00: B
相关文档
最新文档