汇编语言1加到n

合集下载

用汇编语言实现从1加到100的方法(1+2+...+100)

用汇编语言实现从1加到100的方法(1+2+...+100)

⽤汇编语⾔实现从1加到100的⽅法(1+2+ (100)⽤汇编语⾔实现1+2+...+100;课堂作业;计算1+2+...+100DATA SEGMENTCOUNT DW 0 ;计数DATA ENDSSTACK SEGMENT PARA STACKBUF DW 20H DUP (0)LEN EQU $-BUFSTACK ENDSCODESEG SEGMENTASSUME CS:CODESEG,SS:STACK,DS:DATASTART:;初始化堆栈段ss和数据段dsMOV AX,STACKMOV SS,AXMOV SP,LENMOV AX,DATAMOV DS,AXMOV CX,64H ;循环100次MOV AX,0S:ADD COUNT,01HADD AX,COUNTLOOP SMOV DL,ALMOV AL,AHCALL DISP_2_HEXMOV AL,DLCALL DISP_2_HEXCALL DISP_CREFMOV AH,4CHINT 21H;将AL的⾼四位与低四位分别输出DISP_2_HEX:PUSH AXPUSH BXPUSHFMOV AH,0 ;清零MOV BL,10H ;作除法DIV BL ;AL :商⾼位 AH 余数低位CALL DISP_1_HEX ;输出AL的结果MOV AL,AHCALL DISP_1_HEXPOPFPOP BXPOP AXRET;输出AL的数字和字母DISP_1_HEX:PUSH AXPUSH DXPUSHFMOV DL,ALCMP DL,09JBE L_1 ;⼩于等于9则跳过下⼀条语句ADD DL,27H ;⼤于10则转换为⼩写字母并执⾏到下⾯的L_1的RET结束;数字10与字符a差为39(27H);数字输出(1的ascii码为31H)L_1:ADD DL,30H ;数字转换为字符MOV AH,02HINT 21HPOPFPOP DXPOP AXRET;输出回车换⾏DISP_CREF:PUSH DXPUSH AXMOV AH,02HMOV DL,0DHINT 21HMOV DL,0AHINT 21HPOP AXPOP DXRETCODESEG ENDSEND START输出结果为13ba(5050的⼗六进制)以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

x86汇编程序 加法例子

x86汇编程序 加法例子

x86汇编程序加法例子x86汇编语言是一种低级程序设计语言,用于编写计算机程序的一种机器语言。

在x86汇编语言中,加法是最基本的算术运算之一。

下面将列举10个符合要求的x86汇编程序加法例子,并对每个例子进行详细解释。

1. 例子一:```assemblysection .datanumber1 dd 10number2 dd 20result dd 0section .textglobal _start_start:mov eax, [number1] ; 将number1的值加载到寄存器eax 中add eax, [number2] ; 将number2的值加到eax寄存器中 mov [result], eax ; 将eax寄存器中的值保存到result 中; 输出结果mov eax, 4 ; 系统调用编号为4,表示输出mov ebx, 1 ; 文件描述符为1,表示标准输出mov ecx, result ; 输出的字符串地址mov edx, 4 ; 输出的字符串长度int 0x80 ; 系统调用; 退出程序mov eax, 1 ; 系统调用编号为1,表示退出程序 xor ebx, ebx ; 退出码设置为0int 0x80 ; 系统调用```此程序通过使用`mov`和`add`指令来实现加法运算。

首先,将`number1`和`number2`的值加载到寄存器`eax`中,然后使用`add`指令将两个值相加,将结果保存在`eax`中,最后将结果输出到标准输出。

2. 例子二:```assemblysection .datanumber1 db 10number2 db 20result db 0section .textglobal _start_start:mov al, [number1] ; 将number1的值加载到寄存器al中 add al, [number2] ; 将number2的值加到al寄存器中mov [result], al ; 将al寄存器中的值保存到result 中; 输出结果mov eax, 4 ; 系统调用编号为4,表示输出mov ebx, 1 ; 文件描述符为1,表示标准输出mov ecx, result ; 输出的字符串地址mov edx, 1 ; 输出的字符串长度int 0x80 ; 系统调用; 退出程序mov eax, 1 ; 系统调用编号为1,表示退出程序 xor ebx, ebx ; 退出码设置为0int 0x80 ; 系统调用```此程序使用的是8位寄存器`al`进行加法运算。

汇编语言系列之汇编实现简单数学运算

汇编语言系列之汇编实现简单数学运算

汇编语⾔系列之汇编实现简单数学运算⽬录1.计算S=1+2×3+3×4+4×5+···+N(N+1)1.1设计要求:1.2设计思路:1.3程序清单:1.4程序运⾏结果及分析:2.计算N!2.1设计要求:2.2设计思路:2.3程序清单:2.4程序运⾏结果及分析:软件:emu8086语⾔:汇编语⾔(Assembly)注意:本⽂列出了两种算术运算的代码,全部代码为博主独⾃⼀⼈编写,会有瑕疵,谨慎使⽤。

1.计算S=1+2×3+3×4+4×5+···+N(N+1)1.1设计要求:设计程序,实现数学公式S=1+2×3+3×4+4×5+···+N(N+1)的算法。

数值N由加键盘输⼊,计算结果在显⽰终端输出。

设计要求:计算结果不超过⼗六位寄存器的存储能⼒,如有溢出提⽰错误。

1.2设计思路:输⼊N值然后把N给BH作为循环次数,通过循环实现乘和累加计算,结果为⼗六进制,通过除以10得到⼗进制,存⼊堆栈再依次输出。

1.3程序清单:DATA SEGMENTpkey DB 0dh,0ah,"pleas input N end by ';' :$"over DB 0AH,0DH,"overflow!",0dh,0ah,'$'result DB 0dh,0ah,'result is:','$'DAT1 DB 8 DUP(0)DATA ENDSSTACK SEGMENTSSTACK DB 100 DUP(0)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTATE:MOV AX,DATAMOV DS,AXLEA SI,DAT1 ;开辟缓冲区LEA DX,pkeyMOV AH,9INT 21H ;DOS功能调⽤,输出字符串LLP:MOV AH,1INT 21H ;DOS功能调⽤,输⼊N值SUB AL,2FHINC DX ;DX计数MOV [SI],AL ;将输⼊的数据存在SI缓冲区INC SICMP AL,0CH ;输⼊为封号结束输⼊JNZ LLPSUB SI,2CMP DX,02H ;DX不为2表⽰输⼊为两位数JNZ LLLPLLP1:MOV CX,1MOV BL,2 ;赋初始值JMP LPLLLP:MOV DI,SISUB DI,1SUB [DI],1MOV AL,10MUL [DI]ADD [SI],AX ;输⼊是两位数时⼗位乘10加个位SUB AH,AHJMP LLP1LP: MOV BH,[SI] ;把循环次数给BHMOV AL,BLINC BLMUL BL ;BL(加1)和AL(原值)相乘给AXADD CX,AX ;AX和CX相加给CX,通过循环实现累加JO OOF ;如果溢出重新输⼊CMP BH,BL ;判断是否达到N值JNZ LPMOV AX,CXMOV CX,0AHMOV BX,0LOP:MOV DX,0DIV CX ;AX表⽰的32位数除以10,商放在AX,余数放在DX INC BXADD DX,30HPUSH DX ;将余数依次压⼊栈CMP AX,0JNZ LOP ;商不为0继续除10LEA DX,resultMOV AH,9INT 21H ;DOS功能调⽤,输出字符串OUTPUT:POP DXMOV AH,2INT 21H ;DX中数据依次出栈并显⽰DEC BXJNZ OUTPUT ;出栈完成后停⽌JMP STATEOOF:LEA DX,overMOV AH,09HINT 21H ;DOS功能调⽤,溢出显⽰JMP STATECODE ENDSEND STATE1.4程序运⾏结果及分析:乘法和累加计算根据流程图⼀步步赋值即可得到,在输⼊两位数和结果转⼗进制输出时遇到了⿇烦,通过查找资料不断尝试,最终找到了简单的解决办法,即输⼊两位时移位累加,输出除以10存⼊堆栈并依次输出显⽰。

汇编语言指令大全.

汇编语言指令大全.
CWD
字扩展指令 CWD(Convert Word to Double Word)
格式: CWD
功能: 将字扩展为双字长,即把AX寄存器的符号位扩展到DX中.
说明:
1. 两个字或字节相除时,先用本指令形成一个双字长的的被除数.
2. 本指令不影响标志位.
3. 示例: 在B1、B2、B3字节类型变量中,分别存有8们带符号数a、b、c,实现(a*b+c)/a运算。
2. AAA的调整操作
若(AL) and 0FH>9 或 AF=1,则调整如下:
(AL)<--(AL)+6,(AH)<--(AH)+1,AF=1,CF<--AF,(AL)<--(AL) and 0FH
AAD
未组合十进制数除法调整指令 AAD(ASCII Adjust for Division)
格式: AAD
在除法指令前对ax合十进制数进行调整以便能用div指令实现两个未组合的十进制数的除法运算其结果为未组合的十进制数商在al中和余数在ahaad指令是在执行除法div之前使用的以便得到二进制结果存于al然后除以oprd得到的商在al中余数在ah示例
AAA
未组合的十进制加法调整指令 AAA(ASCII Adgust for Addition)
3. 加法指令运算的结果对CF、SF、OF、PF、ZF、AF都会有影响.以上标志也称为结果标志.
4. 该指令对标志位的影响同ADD指令.
ADD
加法指令 ADD(Addition)
格式: ADD OPRD1,OPRD2
功能: 两数相加
说明:
1. OPRD1为任一通用寄存器或存储器操作数,可以是任意一个通用寄存器,而且还可以是任意一个存储器操作数.

汇编语言典型例子详解汇编语言例子

汇编语言典型例子详解汇编语言例子

汇编语言典型例子详解汇编语言例子汇编语言典型例子详解汇编语言是一种底层的编程语言,用于与计算机硬件进行交互和控制。

在计算机科学领域,学习汇编语言例子可以帮助我们深入了解计算机的工作原理和底层运行机制。

本文将详细解析几个典型的汇编语言例子,帮助读者更好地理解和掌握汇编语言编程。

1.加法运算的例子假设我们需要编写一个汇编语言程序来实现两个数字的加法运算。

以下是一个典型的汇编语言例子:```assemblysection .datanum1 db 5num2 db 3result db 0section .textglobal _start_start:mov al, [num1] ; 将num1的值加载到寄存器al中add al, [num2] ; 将num2的值与al中的值相加mov [result], al ; 将结果保存到result中; 输出结果到屏幕mov ah, 0x0E ; 设置打印字符的功能码mov al, [result] ; 将结果加载到al寄存器中add al, 30h ; 将结果加上字符'0'的ASCII码,使其变为可打印字符 int 10h ; 调用BIOS中断打印结果; 退出程序mov eax, 1 ; 设置退出系统调用号int 0x80 ; 调用系统调用中断退出程序```上述例子使用了汇编语言的指令和寄存器来完成加法运算,并将结果保存到result变量中。

最后,通过BIOS中断调用将结果打印到屏幕上,并使用系统调用中断退出程序。

2.循环控制的例子下面是一个使用汇编语言编写的简单循环控制的例子:```assemblysection .datacount db 10 ; 循环次数sum db 0 ; 计数器section .textglobal _start_start:xor rcx, rcx ; 清零计数寄存器rcxloop_start:cmp cl, [count] ; 比较计数寄存器和循环次数je loop_end ; 若相等,跳转到循环结束add cl, 1 ; 计数器自增1add [sum], cl ; 将计数器的值加到sum中jmp loop_start ; 无条件跳转到循环开始loop_end:; 输出结果到屏幕mov ah, 0x0E ; 设置打印字符的功能码mov al, [sum] ; 将sum加载到al寄存器中add al, 30h ; 将结果加上字符'0'的ASCII码,使其变为可打印字符 int 10h ; 调用BIOS中断打印结果; 退出程序mov eax, 1 ; 设置退出系统调用号int 0x80 ; 调用系统调用中断退出程序```上述例子使用了循环控制指令来实现对计数器和循环次数的操作。

用汇编语言编写的程序

用汇编语言编写的程序

用汇编语言编写的程序汇编语言是一种低级的编程语言,直接操作计算机硬件。

通过使用汇编语言,程序员可以更加精确地控制计算机的功能和执行过程。

下面将介绍一个用汇编语言编写的程序的例子,以帮助读者更好地理解汇编语言的特点和用途。

一、程序概述这个用汇编语言编写的程序的功能是计算从1到100的所有整数的和。

通过使用汇编语言的特性,我们可以实现高效的计算过程,以最小的资源消耗完成任务。

二、程序设计程序的设计思路是使用循环结构,从1开始累加到100,并将结果保存在寄存器中。

具体的程序设计如下:1. 初始化寄存器:将累加结果的寄存器置零,准备开始累加过程;2. 设定循环起始值:将循环计数器设为1,作为累加的起始值;3. 累加过程:将当前的累加结果与循环计数器相加,将结果保存在累加结果的寄存器中;4. 判断循环结束条件:如果循环计数器小于等于100,则继续循环,否则跳转到结束;5. 循环迭代:将循环计数器加1,准备下一次循环;6. 结束:输出最终的累加结果。

三、程序实现下面是具体的汇编代码实现:```assemblysection .datasum db 0 ; 累加结果count db 1 ; 循环计数器section .textglobal _start_start:mov al, 0 ; 初始化累加结果寄存器 mov bl, 1 ; 初始化循环计数器add al, bl ; 累加过程inc bl ; 循环迭代cmp bl, 101 ; 判断循环结束条件 jle _start ; 继续循环; 输出最终累加结果mov ah, 0x0emov al, 'T'int 0x10mov ah, 0x0e mov al, 'h' int 0x10mov ah, 0x0e mov al, 'e'int 0x10mov ah, 0x0e mov al, ' 'int 0x10mov ah, 0x0e mov al, 's'int 0x10mov ah, 0x0e mov al, 'u'int 0x10mov ah, 0x0e mov al, 'm' int 0x10mov ah, 0x0e mov al, ' 'int 0x10mov ah, 0x0e mov al, 'i'int 0x10mov ah, 0x0e mov al, 's'int 0x10mov ah, 0x0e mov al, ':'int 0x10mov ah, 0x0e mov al, ' 'int 0x10mov ah, 0x0e mov al, '5'int 0x10mov ah, 0x0emov al, '0'int 0x10mov ah, 0x0e mov al, '5'int 0x10mov ah, 0x0e mov al, '0'int 0x10mov ah, 0x0e mov al, '0'int 0x10mov ah, 0x0e mov al, '0'int 0x10mov ah, 0x0e mov al, 0x0d int 0x10mov ah, 0x0e mov al, 0x0aint 0x10; 程序结束mov eax, 1xor ebx, ebxint 0x80```四、程序运行结果以上的程序经过编译、链接后可以在计算机上运行。

汇编语言最全指令表

汇编语言最全指令表

伪指令•1、定位伪指令ORG m•2、定义字节伪指令DB X1,X2,X3, (X)•3、字定义伪指令DW Y1,Y2,Y3,…,Yn4、汇编结束伪指令END寻址方式MCS-51单片机有五种寻址方式:1、寄存器寻址2、寄存器间接寻址3、直接寻址4、立即数寻址5、基寄存器加变址寄存器间接寻址6、相对寻址7、位寻址数据传送指令一、以累加器A为目的操作数的指令(4条)•MOV A,Rn ;(Rn)→A n=0~7•MOV A,direct ;(direct )→A•MOV A,@Ri ;((Ri))→A i=0~1•MOV A,#data ;data →A二、以Rn为目的操作数的指令(3条)MOV Rn ,A;(A)→ RnMOV Rn ,direct;(direct )→ RnMOV Rn ,#data;data → Rn•三、以直接寻址的单元为目的操作数的指令(5条)MOV direct,A;(A)→directMOV direct,Rn;(Rn)→directMOV direct,direct ;(源direct)→目的directMOV direct,@Ri;((Ri))→directMOV direct,#data;data→direct四、以寄存器间接寻址的单元为目的操作数的指令(3条)MOV @Ri,A;(A)→(Ri)MOV @Ri,direct;(direct)→(Ri)MOV @Ri,#data;data→(Ri)五、十六位数据传送指令(1条)MOV DPTR,#data16;dataH→DPH,dataL →DPL六、堆栈操作指令进栈指令PUSH direct ;(SP)+1 →SP ,(direct)→ SP 退栈指令POP direct七、字节交换指令(5条)•XCH A,Rn ;(A)→ß(Rn)•XCH A,direct ;(A)→ß(direct)•XCH A,@Ri ;(A)→ß((Ri))•八、半字节交换指令•XCHD A,@Ri ;(A)0~3→ß((Ri))0~3九、加器A与外部数据存贮器传送指令(4条)•MOVX A,@DPTR ;((DPTR))→A•MOVX A,@ Ri ;((Ri))→A i=0,1•MOVX @ DPTR ,A ;(A)→(DPTR)•MOVX @ Ri , A ;(A)→(Ri)i=0,1 十、查表指令(i)MOVC A ,@ A+PC ;((A)+(PC))→A•(ii)MOVC A ,@A+ DPTR ;((A)+(DPTR))算术运算指令一、不带进位的加法指令(4条)ADD A,Rn ;(A)+(Rn)→AADD A,direct ;(A)+(direct)→AADD A,@Ri ;(A)+((Ri))→AADD A,#data ;(A)+#data→A二、带进位加法指令(4条)ADDC A,Rn ;(A)+(Rn)+CY→AADDC A,direct ;(A)+(direct)+CY →AADDC A,@Ri ;(A)+((Ri))+CY →AADDC A,#data ;(A)+ #data +CY →A三、增量指令(5条)INC A ;(A)+1 →A•INC Rn ;(Rn)+1 → Rn•INC direct ;(direct)+1 → direct•INC @Ri ;((Ri))+1 →(Ri)•INC DPTR ;(DPTR)+1 →DPTR四、十进制调整指令(1条)DA A减法指令一、带进位减法指令SUBB A,RnSUBB A,directSUBB A,@RiSUBB A,#data二、减1指令(4条)DEC ADEC RnDEC directDEC @Ri乘法指令MUL AB除法指令DIV AB逻辑运算指令累加器A的逻辑操作指令一、累加器A清0CLR A二、累加器A取反CPL A三、左环移指令RL A四、带进位左环移指令RLC A五、右环移指令RR A六、带进位右环移指令RRC A七、累加器ACC半字节交换指令SWAP A两个操作数的逻辑操作指令逻辑与指令ANL A,RnANL A,direct ANL A,@Ri ANL A,#data ANL direct ,A ANL direct,#data逻辑或指令ORL A,RnORL A,directORL A,@RiORL A,#dataORL direct,AORL direct,#data逻辑异或指令XRL A,RnXRL A,directXRL A,@RiXRL A,#dataXRL direct,AXRL direct,#data 位操作指令位变量传送指令MOV C,bitMOV bit,C 位变量修改指令CLR CCLR bitCPL CCPL bitSETB CSETB bit位变量逻辑与指令ANL C,bitANL C,/bit位变量逻辑或指令ORL C,bitORL C,/bit控制转移指令无条件转移指令(4条)1、短跳转指令AJMP addr11 ;先(PC)+2→PC ;addr11→PC10~0 ,(PC15~11)2、跳转指令LJMP addr16 ;Addr16→PC3、转移指令4、SJMP rel ;先(PC)+2→PC;后(PC)+rel→PC4、寄存器加变址存器间接转移指令(散转指令)JMP @A+DPTR ;(A)+(DPTR)→PC条件转移指令(8条)一、测试条件符合转移指令JZ rel ;当A=0 时,(PC)+rel→(PC)转移;当A≠0时,顺序执行。

汇编语言设计-算术运算指令

汇编语言设计-算术运算指令

NEG指令是对指令中的操作数取补,再将结果送回。因 对一个操作数求2的补码,相当于0减去此操作数,所以NEG 指令执行的也是减法操作。
说明:0 – OPRD 又相当于: ①、FFH-OPRD+1 (字节操作)或
②、FFFFH-OPRD+1(字操作)。即将OPRD内容变反加1
例:若(AL)=13H 0000 0000 执行 NEG AL – 0001 0011
0000 0110 + 1111 1100 1← 0000 0010
6 + 252
258>255
+6 + (–4)
+2
CF=1 溢出
OF=0 不溢出
ⅲ、无符号数不溢出,带符号数溢出:
二进制加法 认作无符号 认作带符号数
0000 1000 + 0111 1011
1000 0011
8 + 123
131 CF=0 无溢出
2、带进位位的加法指令ADC ADC dest , src ; dest←dest+src+CF
ADC主要用于多字节运算,ADC对标志位的影响同ADD。 例:计算 1234FEDCH+33128765H 分别存于数据段指
定的区域中,低位在前,高位在后,相加后其和存入前一个双 字所在的区域中。 (SI)→1000H DCH (41H)
+ 39H 0011 1001
0110 1110
则(AL)=6EH,低4位为非法码,故需调整。
4、组合十进制加法调整指令DAA
(BCD码的加法十进制调整指令)
格式:DAA
功能:对组合BCD码相加的结果进行调整,使结果仍为 组合的BCD码。

汇编语言总结

汇编语言总结

执行指令 SAHF 后 (FLAGS)=0400H ③ 标志寄存器进栈指令 PUSHF 功能:将标志寄存器内容压入堆栈 即: (SP)–2→SP (FLAGS)→↓(SP) 例 3:需要将(FLAGS)→AX 要用以下两条指令来实现: PUSHF POP AX 问题:可以用 LAHF 吗? ④ 标志寄存器出栈指令 POPF 功能:将栈顶的内容送入标志寄存器 例:已知: (FLAGS)=0485H, (AX)=0000H,执行以下指令后: PUSHF ① PUSH AX ② POPF ③(FLAGS)=0000H 结果为: (FLAGS)=0000H, (AX)=0000H 5.标志位操作指令 CLC 使 CF=0 (Clear carry) 对进位标志 CF 操作指令 CMC 使 CF 取反 (Complement carry) STC 使 CF=1 (Set carry) CLD 使 DF=0 (Clear direction ) 对方向标志 DF 操作指令 STD 使 DF=1 (Set direction) CLI 使 IF=0 (Clear interrupt) 对中断标志 IF 操作指令 STI 使 IF=1 (Set interrupt)
寄存器方式操作数在寄存器中寻址方式存贮器方式操作数在存贮器中端口方式操作数在io端口中2存贮器方式操作数在存储器中寄存器间接方式r变址方式vrf常用于表指针一维数组基址加变址方式virfbr矩阵运算二维数组直接方式n或变量名表达式一寄存器寻址汇编格式
汇编语言总结
第一章
汇编语言:一种用符号书写的、其主要操作与机器指令一一对应,并遵循一定语法规则的计 算机语言。 汇编源程序:用汇编语言编写的程序——类似于高级语言编写的源程序。 汇编程序: 把汇编源程序翻译成目标程序的语言加工程序——类似于高级语言的编译程序。 汇编: 汇编程序进行翻译的过程 —— 类似于高级语言的编译过程。 伪指令: 源程序中告诉汇编程序如何进行汇编工作的命令。 例如:程序的开始、结束,数据类型和存放的位置 寄存器:一些暂时存放数据的临时存储单元。 (1) 寄存器是中央处理器内的组成部份; (2) 寄存器是有限存贮容量的高速存贮部件; (3) 寄存器是计算机系统获得操作资料的最快速途径。 EAX (累加器)Accumulator ECX (计数寄存器)Count EBX (基址寄存器)Base EDX (数据寄存器)Data(注) ESP(Stack Pointer) ,称为堆栈指示器,存放的是当前堆栈段中栈顶的偏移地址; EBP(Base Pointer),为对堆栈操作的基址寄存器; ESI(Source Index),称为源变址寄址器;字符串指令源操作数的指示器。 EDI(Destination Index),称为目的变址寄存器;字符串指令目的操作数的指示器。注 代码段寄存器 堆栈段寄存器 数据段寄存器 附加数据段寄存器 附加数据段寄存器 附加数据段寄存器 CS SS DS ES FS GS

汇编语言程序设计

汇编语言程序设计

第四章汇编语言程序设计(assembly languageprogramming)§4.1 汇编语言(assembly language)一.概述汇编语言:一种符号语言,它用助记符表示指令的操作码和操作数,用标号或符号代表地址、常量和变量,与机器语言几乎一一对应汇编语言程序:用汇编语言编写的程序汇编:把汇编语言源程序翻译成机器语言目标程序的过程汇编语言源程序手工汇编或汇编程序机器语言目标程序汇编程序:用来完成汇编工作的程序,有小汇编ASM宏汇编MASM动态调试程序DEBUG二.汇编语言的语句格式: [名称] 指令助记符 [操作数] [;注释]带方括号的项有时可没有,注释项完全可以没有每个部分用空格分开每行最多可有132个字符,但最好不要超过屏宽80语句可分成指令性语句和指示性语句(伪指令语句)指令性语句汇编后可生成机器码[标号:] 指令助记符 [操作数] [;注释]指示性语句指示汇编程序处理一些工作[名称] 伪指令(指示符) [操作数] [;注释]1.名称(或称标识符)给指令或存储单元地址起的名字,由字母、数字、字符组成字母:A~Z ,a~z数字:0~9字符:可打印+-*/=()[]〈〉;.' ’ ,_:?@$&(非打印空格制表符TAB 回车换行)(界符:,;:.()[]〈〉+-*/=?_@&$' ’界符用来表示某个标志的结束)数字不能作名称的第一个字符,圆点.仅能作第一个字符保留字不能作标识符($、?是保留字,与其它字符组合除外)名称最长为31个字符当名称后跟冒号,表示该名称是其后指令的标号,代表该指令的开始地址,其他指令可以用该标号作为转移地址当名称不跟冒号,它可能是标号或变量名,伪指令前的名称不跟冒号冒号隐含NEAR属性,例:供段内调用写成 OUTPUT:OUT DX ,AL供段间调用写成 OUTPUT OUT DX ,AL2.指令助记符8086/8088指令,也可以是伪指令,如果指令有前缀(LOCK、REP等)则前缀和指令用空格分开3.操作数指令执行的对象,可能有一、二个或没有名称指令助记符操作数注释RET ;返回(无操作数)COUNT: INC CX ;CX加1(1个操作数)MOV AL,BL ;ALBL(2个操作数)伪指令可有多个操作数COST DB 3,4,5,6,7,8 ;(6个操作数,用逗号分开)操作数可以是常数、寄存器名、标号、变量、表达式,MOV AX,[BP+4];(第二个操作数为表达式)4.注释可选项,使程序易读,汇编时不作处理注释前面要加分号,它可位于操作数之后,也可位于行首三.常量与变量1.常量,也叫常数,没有属性的纯数,汇编时已确定的值·数字常量为0~65535中的数(16位寄存器使用,伪操作可定义32位),进制加后缀说明,十进制加D(可省),二进制加B,八进制加Q,十六进制加H,若十六进制第一位为字母,则前头应加0·字符和字符串叫串常量,是ASCII码字符串,必须加单(或双)引号例:‘A’,“ABC”,汇编后变成41H,414243H2.变量,用于表达数值(或串)的标识符,有三个属性① 段属性(SEGMENT)② 偏移地址属性(OFFSET)③ 类型属性(TYPE),用DB、DW、DD定义§4.2 伪指令(pseudo-instruction)一.符号定义伪指令1.等值EQU格式:符号名 EQU 表达式用来给符号定义一个值,程序中出现该符号就用其值代替,EQU只能定义一次DATA EQU 1234 ;代表一个数XYZ EQU ALPHA[SI] ;代表一个地址2.等号 =格式:符号名 = 表达式意义与EQU一样,但程序中可重新定义符号的值EMP = 6 ;EMP代表6EMP =EMP + 1 ;EMP现在代表73.解除PURGE格式:PURGE 符号名(符号1,符号2,……,符号n)用于解除所定义的符号使该符号在以后的定义中有效例:原定义 TAB EQU 5可用 PURGE TAB 来解除然后可重新定义 TAB EQU 10二.数据定义伪指令用于预置存储器或定义变量1.定义字节DB格式:[变量名称] DB 表达式例:DATA1 DB 2,3,4,5;从DATA1单元开始存放4字节数据2.定义字DW格式:[变量名称] DW 表达式例:TAB DW 1234H;TAB单元内容为34H,TAB+1单元内容为12H 3.定义双字DD格式:[变量名称] DD 表达式每个数据二字(四字节)低位部分在低地址,高位部分在高地址·用DB/DW/DD定义的数每行不得超过16项,超过16项必须换行DB/DW/DD用法<1> SUM DB ? ;给SUM单元分配一个字节,内容未定<2> TAB DB 20 DUP(0);给TAB开始单元分配20字节,内容为0<3> TIME DW 100 DUP(?);给TIME开始单元分配100字,内容未定<4> ADDR DD TABLE ;TABLE的地址(双字)给ADDR例:DATA SEGMENTORG 100HTABLE DB 1,2,3,4ADDR DD TABLEDATA ENDS假设汇编后DS=13A2H(如果ADDR用DW定义,只得偏移量)(如果TABLE是变量,ADDR得地址,是常量,ADDR得数值)<5> LETTER DB ‘ABCDEFG’;将字符串以ASCII码形式填入LETTER开始的内存<6> HIS DB 3 DUP(‘WELCOME!’,0DH,0AH);从HIS单元开始重复3次存放WELCOME!和回车换行符4.标号LABEL格式:标号名 LEBEL 类型标号用于说明可执行代码在汇编语言程序中的位置,即符号地址,供调用和转移之用标号有三个属性段属性偏移量属性距离属性(即格式中的类型):NEAR(近程)和FAR(远程)NEAR:本标号为段内标号,调用本标号只提供偏移地址,段基址为当前代码段FAR:本标号为段间标号,调用本标号提供偏移地址和段基址一个具有NEAR属性的标号也可用标号加冒号作后缀,并排列在代码行的开头来隐含如 AGAIN LABEL NEARXOR AX,BUFF[BX]可写成 AGAIN:XOR AX,BUFF[BX]例:ROOT LABEL NEAR ;以下程序所用的ROOT标号是段内属性COMP PROC NEAR ;以下程序所用的过程下的标号是段内属性TIME PROC FAR ;以下程序所用的过程下的标号是段间属性三.运算符1.算术运算符+、-、*、/、MOD即加、减、乘、除、除法取余数(如19 MOD 7=5)操作数是数字,结果也是数字存储器地址运算时只有加减,例TAB+2、BETA-5等2.逻辑运算符AND、OR、XOR、NOT即与、或、异或、非操作数是数字,结果也是数字例:AND BX,DAT AND 0FEH3.关系算符EQ、NE、LT、GT、LE、GE即相等、不等、小于、大于、小于等于、大于等于若关系是假结果为0,若关系是真结果为0FFFFH例:MOV BX,PAD LT 3则PAD的值小于3时,汇编成MOV BX,0FFFFH否则,汇编成MOV BX,04.分析运算符可把存储器操作数分解成它的组成部分,如段值、段内偏移量、类型5.合成算符由已存在的存储器操作数生成一个段值与偏移量相同,而类型不同的新的存储器操作数以下讨论分析算符和合成算符1.取段基址SEG它加于一个变量或标号之前,回送段基址,例:ASSUME CS:SEG BEGIN ;令CS为BEGIN程序段段基址MOV AX,SEG VARN ;将VARN的段基址送AX2.取偏移量OFFSET它加于一个变量或标号之前,取其偏移量,例:MOV BX,OFFSET SUM ;将SUM的段内偏移量存入BX3.取类型码TYPE它加于一个变量或标号之前,取其类型代码DB DW DD DQ DT NEAR FAR1 2 4 8 10 -1 -2例:NG1 DB ‘A’,‘D’,3NG2 DW 88,265……MOV AL,TYPE NG1 ;NG1定义字节,AL 1MOV AL,TYPE NG2 ;NG2定义字,AL 24.取长度LENGTH它加于一个变量之前,取分配给变量的项数例:TAB DB 150 DUP(?);150项,150字节FUM DW 150 DUP(?);150项,300字节则,MOV CX,LENGTH TAB ;CX 150MOV AX,LENGTH FUM ;AX 150·注意:LENGTH返回的存储区必须用DUP()来定义,否则返回为1 5.取字节数SIZE它加于一个变量之前,取回变量所占字节总数,有SIZE = LENGTH * TYPE由上例,LENGTH TAB = 150,TYPE TAB = 1LENGTH FUM = 150,TYPE FUM = 2可知: SIZE TAB = 150SIZE FUM = 300以上5个叫数值返回算符6.类型指示PTR格式:类型 PTR 地址表达式表示PTR右边的(存储器)操作数是左边的类型,有:BYTE、WORD、DWORD、NEAR、FAR例:INC BYTE PTR [BX] ;将BX指向的单元字节加1MOV WORD PTR [DI],99 ;立即数99送DI指向的字中JMP NEAR PTR FOK ;以近程方式跳转到FOK(只取FOK偏移地址)7.指定符THIS(合成算符)用于定义当前所指单元中的类型格式:THIS 类型/距离经THIS定义过的标号具有当前汇编段、偏移量和所规定的类型或距离等属性,例:FOOB EQU THIS BYTE;下面的字类型变量FOOW在这里指定为字节型FOOBFOOW DW 120 DUP(?)定义后,对同一数据块(FOOB和FOOW有相同的段和段内偏移量)有两种类型访问FOOB时为字节操作,访问FOOW时为字操作ADD AL,FOOB[3] ;将数组第四字节与AL相加MOV AX,FOOW[4]将数组第五六字节组成的字送AX也可以这样来构成FOOB:FOOB EQU BYTE PTR FOOW又例:DATAF EQU THIS FARDATAN:MOV AX,FOO这时 JMP DATAN为近程转移JMP DATAF为远程转移8.段修改符:用于对某一地址表达式指定临时段基址,如MOV AX,ES:[BX];指定ES为BX的段基址,对当前指令有效9.短程符SHORT与NEAR、FAR功能类似,位移量一字节范围 -128~+127,对应一条短转移指令例:JMP SHORT LAB;转移到标号LAB的地址10.方括号 [ ]表示操作数(加方括号)是一个地址偏移量,不是数值格式:[表达式] 或者 [表达式][ ]例:MOV [BX],AX ;将AX内容送BX所指单元MOV [BX+7],AX ;将AX内容送BX+7所指单元MOV AX,[BX][SI] ;将BX+SI所指单元内容送AX11.取高/低字节HIGH/LOW用来分离常量的高/低字节,对存储器操作数无效例:DATA EQU 789AHMOV AL,HIGH DATA ;AL=78HMOV AL,LOW DATA ;AL=9AH四.段定义伪指令1.SEGMENT—ENDS格式:[段名] SEGMENT [定位类型] [组合类型] [‘类别名’]┇[段名] ENDS·段名·定位类型(Align),给出实际段地点的种类或段长度的信息<1> PARA 段起始地址从一个节(paragraph)的边界开始<2> BYTE 段地址可从任意绝对地址开始<3> WORD 段地址从任意一个字的边界开始<4> PAGE 段地址从某一页的边界开始(一页等于256字节)<5> INPAG 段长度小于一页未说明定位类型时则默认为PARA·组合类型(Combine),又称联合类型,程序中各程序段的连接和定位方法<1> PUBLIC 将段名相同的程序段(亦称模块)依此紧密连接,但彼此不相互覆盖<2> COMMON将段名相同的程序段连接,各段都从同一地址开始<3> AT表达式段定位在由表达式(结果必须是常数)所指定的节的边界上例:AT 1234H,则段地址被定位在物理地址为12340H处,如果希望从12345H开始,则在SEGMENT命令的下一行写上ORG 5AT 不能向前引用<4>STACK 表示这个段是运行期间的堆栈段<5>MEMORY 该段是相互连接的几个段中地址最高的段<6>NONE本段与其他段无组合关系未说明联合类型时则默认为NONE,不和别的段连接·‘类别名’(Class),也叫组名,加单引号,汇编后类别名相同的程序段代码集中在一起定位,形成一个统一的物理段,类别名可自定,约定的有CODE (代码段)、DATA(数据段)、STACK(堆栈段)、CONST(常数)、MEMORY(存储)等2.ASSUME段寄存器说明伪指令,指明所定义的段名所使用的段寄存器(告诉汇编程序在运行期间通过哪一个段寄存器寻址才能找到所要的指令和数据),本语句一般在定义的代码段中第一条出现格式:ASSUME 段寄存器:段名 [,…]例: ASSUME CS:CODE,DS:DATA ;用SEGMENT—ENDS定义ASSUME CS:SEG KGF,DS:SEG BEGIN;由算符定义ASSUME ES:NOTHING ;用关键字定义,表示不使用ES(取消ES段寄存器)(保留字NOTHING在这里作为一个段名参数,ASSUME NOTHING表示取消所有段寄存器,各个段寄存器只能在指令性语句中由MOV指令赋值)·ASSUME只是设定段寄存器与逻辑段的对应关系,并没给段寄存器装入实际值,所以程序中必须对DS、ES、SS赋值,而CS由系统赋值3.ORG定点伪指令(段内定位),用以确定下一条指令(或变量)在当前段中的偏移地址格式:ORG 表达式表达式以65536(64K)为模计算,超过64K则取其余数本语句前未定义过的变量不可出现在表达式中,表达式可包含$(程序计数器当前值)如:ORG OFFSET $+1000表达式必须为正值,若为负值,就会从当前段的地址高端开始表达式最好不要写成OFFSET $-1000,以免把汇编过的1000个字节覆盖掉ORG指令不能带标识符,如START:ORG 0和SKIP ORG 100都是错的例:CODE SEGMENT ;段起始ORG 100H ;本程序代码从偏移地址100H开始装入ASSUME CS:CODE ;装入代码段地址到CS中START:IN AL,30H ;程序段SHL AL,1OUT 32H,ALJMP STARTCODE ENDS ;程序段结束END START ;汇编结束例:DATA SEGMENTORG 50HDAT DW 1,2,$+1┇DATA ENDS注意DAT不能定义为字节,否则与$不匹配五.过程定义伪指令格式:过程名 PROC 属性┇过程体RET过程名 ENDP·过程名不可缺省,它和标号一样有三个属性:段属性、偏移地址属性、距离属性·距离属性在PROC后指定,有NEAR和FAR,如果希望过程能让别的程序调用,则必须是FAR属性·一个过程允许多个入口,入口处有标号,标号要说明距离属性例:延时100ms子程序DELAY PROC ;隐含NEARMOV BL,10 4TDLY1: MOV CX,2801 ;内循环延时10ms 10TWAIT0: LOOP WAIT0 9/5T DEC BL 2TJNZ DLY1 8/4TRET 8TDELAY ENDP六.结束伪指令·NAME:给模块(源程序)命名格式:NAME 模块名称它出现在源程序的最前端·END:汇编结束格式:END [标号名]它通知汇编程序本模块汇编到此结束标号名是可选项,若选取,应指向执行本程序的起始地址若一个源程序是多模块,只有主模块的END后加标号,子模块只有END七.宏指令宏指令:在汇编语言源程序中多次重复出现的程序段,用一个名字来定义,然后当成一条指令来使用宏汇编:源程序中的宏指令经汇编程序翻译后扩展成对应程序段的机器码宏指令用MACRO—ENDM来定义,如:CRLF MACROMOV DL,0DHMOV AH,02HINT 21H┇ENDM(CRLF作回车换行)§4.3 汇编语言程序设计(assembly language programming)一.设计要求1.程序简明、易读、易调试、易修改2.程序占用内存要少(包括程序长度及运行时所需空间)3.程序运行速度要快二.基本设计方法1.选择合适的计算方法2.绘制程序流程图3.编制程序4.上机调试三.汇编语言程序格式和基本结构一般一个完整的汇编语言程序至少应包括以下三个程序段简化段格式:.MODEL SMALL.STACK 64H.DATA……;紧接指令代码从偶地址开始存放.CODESTART: MOV AX,@DATAMOV DS,AX……END STARTDATA SEGMENT ‘DATA’┇数据段DATA ENDSSTACK SEGMENT ‘STACK’┇堆栈段STACK ENDSCODE SEGMENT ‘CODE’ASSUME CS:CODE,DS:DATA,SS:STACKSTART:MOV AX,DATAMOV DS,AXMOV AX,STACKMOV SS,AX┇代码段CODE ENDSEND START程序的基本结构分为顺序结构、分支结构、循环结构和子程序结构(一)顺序结构一种简单程序,按顺序执行例1.将200H单元的低4位和高4位分别送入201H和202H单元的低4位,这二单元的高4位清0200HX X201H 0202H 0DATA SEGMENTORG 200HBCD DB 47HDB 2 DUP(?)DATA ENDSSTACK SEGMENTSTA DB 20 DUP(?)TOP EQU LENGTH STASTACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTART:MOV AX,DATAMOV DS,AXMOV AX,STACK MOV SS,AXMOV AX,TOPMOV SP,AXMOV BX,OFFSET BCD MOV AL,[BX]AND AL,0FHMOV [BX+1],AL MOV AL,[BX]MOV CL,4ROL AL,CLAND AL,0FHMOV [BX+2],AL HLTCODE ENDS END START例2.将ADDR1和ADDR2两单元开始的二个16位无符号数相加,考虑到进位,将其结果存放在SUM开始的三个单元中DATA SEGMNETADDR1 DW 7854HADDR2 DW 9981HSUM DB 3 DUP(0)DATA ENDSSATCK SEGMENTSTA DB 20 DUP(?)TOP EQU LENGTH STASTACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTART: MOV AX,DATAMOV DS,AXMOV AX,STACKMOV SS,AXMOV AX,TOPMOV SP,AXMOV AX,ADDR1ADD AX,ADDR2MOV WORD PTR SUM,AXADC SUM+2,0HLTCODE ENDSEND START例3.查表将DATA1单元中字节类型数据(0~0FH)转换成ASCII码,并存入ASCII单元中DATA SEGMENTASCTAB DB 30H,31H,32H,33H,34H,35H,36H,37HDB 38H,39H,41H,42H,43H,44H,45H,46HDATA1 DB 09HASCII DB ?DATA ENDSSTACK SEGMENT STACKDW 10 DUP(?)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTART PROC FARASCTAB 30 031 1┇93941 A42 B┇46 F┇ASCIIPUSH DSMOV AX,0PUSH AXMOV AX,DATAMOV DS,AXMOV BX,OFFSET ASCTABMOV AL,DATA1XLATMOV ASCII,ALRETSTART ENDPCODE ENDSEND START例4.将200H和201H单元字节的高4位对调,低4位不变CODE SEGMENT200H201HORG 200HDATA1 DB 0F3H,47HASSUME CS:CODE,DS:CODESTART:MOV AX,CODEMOV DS,AXMOV CL,4MOV AX,WORD PTR DATA1 ;AX=47F3HROL AX,CL ;AX=7F34H ROL AH,CL ;AX=F734H ROL AL,CL ;AX=F743H MOV WORD PTR DATA1,AXHLTCODE ENDSEND START(二)分支结构通过判断产生分支,借助于条件转移指令跳转到相应的分支地址执行分支程序分支程序由三部分组成① 测试部分,负责产生决定分支的条件② 定向部分,根据测试条件是否满足,决定程序是否分支③ 标注部分,标明分支的去向利用跳转表也可使程序转移到分支地址例1.16位二进制补码X在DATA1单元,求其绝对值送DATA2单元(设X≠8000H)∣X∣= X,X≥0-X, X<0DATA SEGMENTDATA1 DW 9F87HDATA2 DW ?DATA ENDSSTACK SEGMENTSTA DB 20 DUP(?)TOP EQU LENGTH STA STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACK START:MOV AX,DATAMOV DS,AXMOV AX,STACKMOV SS,AXMOV AX,TOPMOV SP,AXMOV AX,DATA1AND AX,AXJNS ABS0NEG AXABS0: MOV DATA2,AXHLTCODE ENDSEND START例2.多重分支学生成绩按分数段划分为:A、90~100(5AH~64H)B、80~89 (50H~59H)C、70~79 (46H~4FH)D、60~69 (3CH~45H)E、 <60 ( <3CH)已知分数存放在MARK单元,请用ASCII码的A、B、C、D、E去代表MARK单元中的分数所属的段,并存于GRADE单元DATA SEGMENTMARK DB 81GRADE DB ?DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA START:MOV AX,DATAMOV DS,AXMOV BX,OFFSET MARKMOV AL,[BX]CMP AL,3CHJC LPECMP AL,46HJC LPDCMP AL,50HJC LPCCMP AL,5AHJC LPBMOV AL,41H ;‘A’JMP SHORT DONELPB: MOV AL,42H ;‘B’JMP SHORT DONELPC: MOV AL,43H ;‘C’JMP SHORT DONELPD: MOV AL,44H ;‘D’JMP SHORT DONELPE: MOV AL,45H ;‘E’DONE: MOV BX,OFFSET GRADE MOV [BX],ALHLTCODE ENDSEND START法2:直接查表转换(顺序结构)DATA SEGMENTTAB DB ‘EEEEEEDCBAA’MARK DB 81GRADE DB ?DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA START:MOV AX,DATAMOV DS,AXMOV BX,OFFSET TABMOV AL,MARKMOV AH,0MOV CL,10DIV CLXLATMOV GRADE,ALHLTCODE ENDSEND START(三)循环结构使机器重复执行一系列指令,是一种闭合的分支结构循环程序由四部分组成① 初始化部分(或预置部分),负责设置循环初值② 处理部分,循环过程的主体③ 控制部分,修改初值,判断是否循环循环次数由一计数器控制循环次数由某一指定条件是否满足来决定④ 结束部分,处理循环程序的最后结果例1.将DTAB单元开始的一组字节补码数(≤255个)求平均值,结果存入AVE单元,若结果为负,在SYM置FFH否则置0DATA SEGMENTDTAB DB 0FDH,0FCH,05H,0F8H,……DB 08H,25H,83H,97H,……COUNT EQU $-DTABAVE DB ?SYM DB ?DATA ENDSSTACK SEGMENT STACKSTA DB 20 DUP(?)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACK AVER PROC FARSTART:PUSH DSMOV AX,0PUSH AXMOV AX,DATAMOV DS,AXLEA BX,DTABMOV CX,COUNTXOR DX,DXNEXT: MOV AL,[BX]CBWADD DX,AXINC BXLOOP NEXTMOV AX,DX MOV CL,COUNTIDIV CLMOV AVE,ALMOV SYM,0AND AL,ALJNS DONEMOV SYM,0FFHDONE: RETAVER ENDPCODE ENDSEND START循环控制方法:循环次数由计数器控制例2.将8位二进制小数规格化设需规格化的小数在DATA1单元,要求规格化后使其最高位为1,并存入DATA2单元,办法是把小数左移至最高为位为1为止,左移次数存入DATA3单元,若小数是0,则在DATA2和DATA3单元存入0示例:DATA1 DATA2 DATA322H 88H 02H01H 80H 07HCBH CBH 00H00H 00H 00HDATA SEGMENTDATA1 DB 22HDATA2 DB ?DATA3 DB ?DATA ENDSSTACK SEGMENTSTA DB 20 DUP(?)TOP EQU LENGTH STA STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTART:MOV DATAMOV DS,AXMOV AX,STACKMOV SS,AXMOV AX,TOPMOV SP,AXMOV CL,0MOV AL,DATA1 ;取数AND AL,AL ;设ZF、SF标志JZ DONECHKSF:JS DONEINC CLADD AL,AL ;左移一位JMP SHORT CHKSFDONE: MOV DATA2,ALMOV DATA3,CLHLTCODE ENDSEND START循环控制方法:循环次数由某一指定条件是否满足来决定例3.多重循环将n个无符号字节数从小到大排序,方法是依此比较相邻两单元的数,若前小后大不交换第一轮比较n-1次,最大数沉底(高地址)第二轮比较n-2次,次大数沉到最大数上面第n-1轮比较完若在某一轮比较时没有出现交换,说明顺序已排好,不必后续比较,故设交换标志AH=1代表不交换,AH=2代表有交换DATA SEGMENTLIST DB 18,6,11,3,1,2,3,9,8,7,6 DB 111,110,99,112,115,114,113,98,96,97 COUNT EQU $-LISTDATA ENDSSTACK SEGMENT STACKSTA DW 10 DUP(?)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSET PROC FARSTART:PUSH DSMOV AX,0PUSH AXMOV AX,DATAMOV DS,AXMOV DX,COUNT-1 ;n-1轮(外循环)EXGO:MOV CX,DX ;每轮次数(内循环)MOV AH,01H ;交换标志MOV BX,OFFSET LIST ;数据块首址INGO: MOV AL,[BX]INC BXCMP AL,[BX]JC NEXT ;数1小,不交换XCHG AL,[BX] ;数1>数2,交换DEC BXXCHG AL,[BX]INC BX ;恢复数据指针MOV AH,02H ;有交换标志NEXT: LOOP INGODEC DXJZ DONEDEC AHJNZ EXGODONE: RETSET ENDPCODE ENDSEND START(四)子程序结构基本要求:① 子程序的开始(入口处)应给予一个标号,结束处有返回指令② 通用子程序要说明入口条件(入口参数)和出口条件(出口参数)③ 调用子程序要注意保护现场和恢复现场调用—返回的堆栈操作:CALL target ;段内SPSP-2,[SP+1,SP] IP,IPIP+disp段间SPSP-2,[SP+1,SP] CS,CSsegSPSP-2,[SP+1,SP] IP,IPoffsetRET ;段内IP [SP+1,SP],SPSP+2;段间IP [SP+1,SP],SPSP+2CS [SP+1,SP],SPSP+2RET n ;如上操作后SPSP+n·子程序入口标号应说明距离属性·对于一个FAR过程,过程初必须先保护程序段前缀中的中断指令INT 20H 的断点地址(DS:0000),它是一个程序正常结束退出的中断处理程序例1.将内存200H单元开始的一个五字节十六进制数显示出来(低位在低地址)DATA SEGMENTORG 200HNUM DB 9AH,78H,56H,34H,12HDATA ENDSSTACK SEGMENTSTA DB 20 DUP(?)TOP EQU LENGTH STASTACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTART:MOV AX,DATAMOV DS,AXMOV BX,5MOV AX,STACKMOV SS,AXMOV SP,TOPMOV SI,OFFSET NUMNEXT: MOV DH,[SI+BX-1] ;(不用AL,因调用MOV DL,DH ; display返回时DL→AL)MOV CL,4ROL DL,CLAND DL,0FHCALL DISPLAYMOV DL,DHAND DL,0FHCALL DISPLAYDEC BXJNZ NEXTMOV AX,4C00HINT 21HDISPLAY PROC NEARADD DL,30HCMP DL,3AHJB OKADD DL,07H;(如果DL=3AH,3AH+7=41H是‘A’)OK: MOV AH,02HINT 21HRET。

汇编语言指令详解

汇编语言指令详解

第一讲第三章 指令系统--寻址方式回顾: 8086/8088的内部结构和寄放器,地址分段的概念,8086/8088的工作进程。

重点和纲要:指令系统--寻址方式。

有关寻址的概念;6种大体的寻址方式及有效地址的计算。

教学方法、实施步骤时间分配 教学手段 回 顾 5”×2 板书 计算机 投影仪 多媒体课件等讲 授 40” ×2 提 问 3” ×2 小 结2” ×2教学内容:8086/8088寻址方式操作码 操作数 …… 操作数运算机中的指令由操作码字段和操作数字段组成。

操作码:指运算机所要执行的操作,或称为指出操作类型,是一种助记符。

操作数:指在指令执行操作的进程中所需要的操作数。

该字段除能够是操作数本身外,也能够是操作数地址或是地址的一部份,还能够是指向操作数地址的指针或其它有关操作数的信息。

寻址方式就是指令顶用于说明操作数所在地址的方式,或说是寻觅操作数有效地址的方式。

8086/8088的大体寻址方式有六种。

1.当即寻址所提供的操作数直接包括在指令中。

它紧跟在操作码的后面,与操作码一路放在代码段区域中。

如图所示。

例如:MOV AX,3000H当即数能够是8位的,也能够是16位的。

若是16位的,则存储时低位在前,高位在后。

当即寻址主要用来给寄放器或存储器赋初值。

2.直接寻址操作数地址的16位偏移量直接包括在指令中。

它与操作码—起寄存在代码段区域,操作数一般在数据段区域中,它的地址为数据段寄放器DS加上这16位地址偏移量。

如图2-2所示。

例如:MOV AX,DS:[2000H];图2-2(对DS来讲能够省略成MOV AX,[2000H],系统默以为数据段)这种寻址方式是以数据段的地址为基础,可在多达64KB的范围内寻觅操作数。

8086/8088中允许段超越,即还允许操作数在以代码段、堆栈段或附加段为基准的区域中。

现在只要在指令中指明是段超越的,则16位地址偏移量能够与CS或SS或ES相加,作为操作数的地址。

汇编语言指令格式

汇编语言指令格式
; SS:[SP]←r16/m16/seg
POP r16/m16/seg ; 出栈指令:
; r16/m16/seg←SS:[SP] ; SP←SP+2
• 堆栈的概念 • 堆栈的操作:进栈和出栈 • 堆栈的特点
2021/10/14
什么是堆栈
• 堆栈是一个“先进后 出”的主存区域,位 于堆栈段中,使用SS 段寄存器记录其段地 址。
2021/10/14
例:地址指针的传送
mov word ptr [3060h],0100h mov word ptr [3062h],1450h lds si,[3060h] ;ds=1450h,si=0100h les di,[3060h] ;es=1450h,di=0100h
;mem指定主存的连续4个字节作为逻辑地址( 32位的地址指针),送入DS:reg或ES:reg。
• seg —— 泛指段寄存器CS/DS/ES/SS • m8 —— 泛指8位存储器操作数单元(包括所有寻址方式)
m16 —— 泛指16位存储器操作数单元(包括所有寻址方式) mem —— 泛指m8或m16 • i8 —— 泛指8位立即数 i16 —— 泛指16位立即数 imm —— 泛指i8或i16 • dest—— 泛指目的操作数 src —— 泛指源操作数
2021/10/14
8088指令系统概述
• Intel 8088指令系统共有117条基本指令,可 分成以下 6 类:
① 数据传送类指令 ② 算术运算类指令 ③ 位操作类指令 ④ 串操作类指令 ⑤ 控制转移类指令 ⑥ 处理机控制类指令
2021/10/14
学习指令的注意事项
• 指令功能——该指令能够实现何种操作。通常指令助记符 就是指令功能的英文单词或其缩写形式。

汇编语言设计-算术运算指令

汇编语言设计-算术运算指令

N
传完否?
JNZ AGAIN ;CX≠0,循环
Y
结束

8086算术运算指令可用的BCD码有两种:
ⅰ、组合BCD码:一个字节表示2位BCD码
ⅱ、非组合BCD码:一个字节只用低4位表示1位BCD 码, 高4位为0(无意义)。
例:设(AL)=35,(BL)=39 35H 0011 0101
执行 ADD AL,BL
JNS NEXT
;若SF=0,则(AX)>(BX),转NEXT
XCHG AX,BX ;否则交换
NEXT:HLT
Ⅱ、两负数比较,即A<0,B<0:两负数相减,结果也不会溢出,
仍可用符号标志,若SF=0,则A>B;反之若SF=1,则A<B。
Ⅲ、两异号数比较。当A>0,B<0时,当然的结果应该是A>B,
而且有SF=0。
格式:ADD dest,src ;dest←dest+src
功能:将源操作数与目的操作数相加,将结果送回目的操 作数。指令执行后对各状态标志均产生影响。
例:ADD CX,0F0F0H 设指令执行前(CX)=5463H
0101 0100 0110 0011
思考:
+ 1111 0000 1111 0000
LEA SI,BUF1 ;SI指向BUF1 LEA DI,BUF2 ;DI指向BUF2
取数 传送
MOV CX,100 ;CX放计数初值
AGAIN:MOV AL,[SI] ;取一字节数 MOV [DI],AL ;传送一字节数
修改地址指针 修改计数器
INC SI INC DI DEC CX
;修改地址指针 ;修改计数初值
NEG指令是对指令中的操作数取补,再将结果送回。因 对一个操作数求2的补码,相当于0减去此操作数,所以NEG 指令执行的也是减法操作。

汇编语言常用指令大全

汇编语言常用指令大全

MOV指令为双操作数指令,两个操作数中必须有一个是寄存器.MOV DST , SRC // Byte / Word执行操作: dst = src1.目的数可以是通用寄存器, 存储单元和段寄存器(但不允许用CS段寄存器).2.立即数不能直接送段寄存器3.不允许在两个存储单元直接传送数据4.不允许在两个段寄存器间直接传送信息PUSH入栈指令及POP出栈指令: 堆栈操作是以“后进先出”的方式进行数据操作.PUSH SRC //Word入栈的操作数除不允许用立即数外,可以为通用寄存器,段寄存器(全部)和存储器.入栈时高位字节先入栈,低位字节后入栈.POP DST //Word出栈操作数除不允许用立即数和CS段寄存器外, 可以为通用寄存器,段寄存器和存储器.执行POP SS指令后,堆栈区在存储区的位置要改变.执行POP SP 指令后,栈顶的位置要改变.XCHG(eXCHanG)交换指令: 将两操作数值交换.XCHG OPR1, OPR2 //Byte/Word执行操作: Tmp=OPR1 OPR1=OPR2 OPR2=Tmp1.必须有一个操作数是在寄存器中2.不能与段寄存器交换数据3.存储器与存储器之间不能交换数据.XLAT(TRANSLATE)换码指令: 把一种代码转换为另一种代码.XLAT (OPR 可选) //Byte执行操作: AL=(BX+AL)指令执行时只使用预先已存入BX中的表格首地址,执行后,AL中内容则是所要转换的代码.LEA(Load Effective Address) 有效地址传送寄存器指令LEA REG , SRC //指令把源操作数SRC的有效地址送到指定的寄存器中.执行操作: REG = EAsrc注: SRC只能是各种寻址方式的存储器操作数,REG只能是16位寄存器MOV BX , OFFSET OPER_ONE 等价于LEA BX , OPER_ONEMOV SP , [BX] //将BX间接寻址的相继的二个存储单元的内容送入SP中LEA SP , [BX] //将BX的内容作为存储器有效地址送入SP中LDS(Load DS with pointer)指针送寄存器和DS指令LDS REG , SRC //常指定SI寄存器。

汇编语言 加法指令

汇编语言 加法指令
时,要把进位标志CF的现行值加上去,结果送至目的操作数。 ADC指令影响所有标志位CF、DF、PF、SF、ZF和AF。 ADC指令主要用于多字节运算中。若有两个4字节的数,已 分别放在自FIRST和SECOND开始的存储区中,每个数占4 个存储单元。存放时,最低字节在地址最低处,则可用以下 程序段实现相加。
1、加法指令ADD 2、加进位的加法指令ADC 3、加1指令INC
1. 加法指令ADD
格式:ADD OPRD1,OPRD2 功能:OPRD1OPRD1+OPRD2
说明:完成两个操作数的相加,结果送至目 的操作数OPRD1。其中目的操作数可以是 累加器,通用寄存器及存储器操作数。 ADD指令影响所有标志位CF、DF、PF、 SF、ZF和AF。
例题
MOV AL,-2 ADD AL,1 ADD AL,1 ADC AL,4 MOV AL,-2 ADD AL,1 INC AL ADC AL,4
(AL)=-2 (AL)=-1,CF=0 (AL)=0,CF=1 (AL)=5,CF=0 (AL)=-2 (AL)=-1,CF=0 (AL)=0,CF=0 (AL)=4,CF=0
例题
计算13579BDF H+02468ACE H的值 MOV DX,1357 H MOV AX,9BDF H MOV AX,8ACE H CF=1,(AX)=26ADH MOV DX,0246 H (DX)=159H
3. 加1指令INC
格式:INC OPRD 功能: OPRDOPRD
说明:完成对指定的操作数OPRD加1,然后返回此 操作数。此指令主要用于在循环程序中修改地址指 针和循环次数等。INC指令执行的结果不影响CF位, 而对其他5个标志位AF、OF、PF、SF和ZF有影响。

汇编语言代码例子

汇编语言代码例子

汇编语言代码例子在计算机编程中,汇编语言是一种低级语言,它以机器指令的形式直接操作计算机硬件。

汇编语言具有直接控制硬件、效率高、功能强大等优点,因此在一些系统级编程、驱动开发以及性能优化领域得到广泛应用。

本文将介绍一些汇编语言的代码例子,以帮助读者更好地理解和学习汇编语言。

一、Hello World程序我们先从一个经典的汇编语言例子开始:Hello World程序。

这个程序会在屏幕上显示"Hello, World!"。

```section .data ; 数据段msg db 'Hello, World!', 0 ; 定义一个字符串并以0结尾section .text ; 代码段global _start_start:; 将字符串地址存入寄存器ebxmov ebx, msg; 将字符串长度存入寄存器ecxmov ecx, len; 系统调用号存入寄存器eaxmov eax, 4; 系统调用int 0x80; 程序退出mov eax, 1xor ebx, ebxint 0x80```在这段代码中,`.data` 表示数据段,我们定义了一个字符串`msg`,用来存储要显示的内容。

`.text` 表示代码段,`_start` 是程序的入口点。

程序首先使用 `mov` 指令将字符串的地址存入寄存器 `ebx`,将字符串的长度存入寄存器 `ecx`。

然后使用 `mov` 指令将系统调用号 `4`(表示写入)存入寄存器 `eax`。

接着,使用 `int 0x80` 进行系统调用,将字符串显示在屏幕上。

最后,使用 `mov` 指令将 `1` 存入寄存器 `eax`,表示程序退出。

`xor` 指令用于将寄存器 `ebx` 的值清零,然后再次使用 `int 0x80` 进行系统调用,程序结束。

二、求和程序下面是一个汇编语言的代码例子,用来计算从1到n的所有整数的和。

```section .data ; 数据段n db 10 ; 要计算的整数范围section .text ; 代码段global _start_start:mov eax, 0 ; 将寄存器eax清零,用于存放求和结果xor ecx, ecx ; 将寄存器ecx清零,用于循环计数mov cl, [n] ; 将要计算的整数范围读入寄存器ecxloop_start:add eax, ecx ; 将寄存器ecx的值加到寄存器eax中loop loop_start ; 循环条件减1,如果ecx ≠ 0,则跳转到loop_start; 程序退出mov eax, 1xor ebx, ebxint 0x80```在这段代码中,`.data` 段中定义了一个变量 `n`,表示要计算的整数范围。

51单片机汇编cjnz指令 -回复

51单片机汇编cjnz指令 -回复

51单片机汇编cjnz指令-回复51单片机汇编指令是一种用于控制和操作单片机的低级语言指令,其中的cjnz指令被广泛应用于单片机程序中。

cjnz指令是一种条件转移指令,用于在满足条件时跳转到指定的目标地址。

本文将从以下几个方面详细介绍cjnz指令的使用方法和相关知识。

一、指令格式和功能cjnz指令的格式如下:cjnz A,offset其中,A代表一个寄存器或者内存单元,offset代表跳转的偏移量。

指令的功能是:当A的值不为零时,跳转到指定的目标地址;否则,继续执行下一条指令。

二、指令的使用场景cjnz指令常用于条件判断和循环控制中。

通过判断某个条件是否满足,可以决定程序的执行逻辑,实现程序的控制流程。

1. 条件判断:当需要根据某个特定条件来选择执行不同的代码段时,cjnz指令非常便捷。

通过比较某个寄存器或内存单元的值,可以判断是否满足条件,从而决定是否跳转到相应的代码段。

例如,当某个传感器的数值大于某个阈值时,执行相应的告警处理程序。

2. 循环控制:循环是程序设计中常用的一种结构,而cjnz指令则为循环提供了很好的支持。

通过判断循环计数器是否达到预设的循环次数,可以控制是否跳出循环。

例如,对某个任务进行预定次数的重复执行,可以利用cjnz指令实现循环控制。

三、编写一个基本的cjnz指令的实例程序为了更好地理解和学习cjnz指令,下面我们来编写一个基本的cjnz指令的实例程序。

该程序的功能是:计算1到N的累加和,并将结果保存在一个寄存器中。

首先,我们需要定义一个变量N用来表示累加的范围,并将其存储在某个寄存器中。

MOV R0, N ; 将N的值存储在寄存器R0中然后,我们需要定义两个寄存器,一个用于累加结果,一个用于循环计数。

MOV R1, 0 ; 将累加结果初始化为0MOV R2, 1 ; 将循环计数器初始化为1接下来,我们将通过一个循环来实现累加的功能。

循环的条件是循环计数器R2小于等于N。

微机原理与汇编语言实验03_循环程序设计实验

微机原理与汇编语言实验03_循环程序设计实验

微机原理与汇编语言实验实验三循环程序设计实验一实验目的1、掌握循环程序的设计方法。

2、掌握比较指令、转移指令和循环指令的使用方法。

3、进一步掌握调试工具的使用方法。

二实验预习要求1、复习比较指令、条件转移指令和循环指令。

2、复习循环程序的结构、循环控制方法等知识。

3、读懂“三实验内容”中给出的将十进制数转换为二进制数以及将二进制数转换为十进制数的程序。

4、根据“三实验内容”中给出的流程图和程序框架编写源程序,以便上机调试。

5、从“四实验习题”中任选一道题目,编写源程序,以便上机调试。

三实验内容计算1+2+……n=?,其中n通过键盘输入。

要求在屏幕上提供如下信息:Please input a number(1 627): ;出现此信息后通过键盘输入一个小于628的无符号整数1+2+…..n=sum;其中n为用户输入的数,sum为所求的累加和程序运行情况如下图所示(说明:图中所运行程序允许累加和不大于一个32位二进制数所能表示的范围)。

1、编程指导(1)键盘输入的十进制数如368在计算机中是以33H,36H,38H形式存放的,如何将它们转换为一个二进制数101110000B,以便对累加循环的循环次数进行控制是本程序首先要解决的问题。

将键盘输入的十进制数转换为二进制数的程序清单如下:.model small.stack.dataINF1 DB "Please input a number (0-65535):$"IBUF DB 6,0,6 DUP(?).codeSTART: MOV AX, @dataMOV DS, AXMOV DX, OFFSET INF1MOV AH, 09HINT 21HMOV DX, OFFSET IBUF ;键入一个十进制数(<65535)MOV AH, 0AHINT 21HMOV CL, IBUF+1 ;十进制数的位数送CXMOV CH, 0MOV SI, OFFSET IBUF+2 ;指向输入的第一个字符(最高位)MOV AX, 0 ;开始将十进制数转换为二进制数AGAIN: M OV DX, 10 ;((0⨯10+a4) ⨯10+…) ⨯10+a0MUL DXAND BYTE PTR [SI], 0FHADD AL, [SI]A DC AH, 0I NC SILOOP AGAINMOV AH, 4CHINT 21HEND START本程序功能:从键盘接收一个无符号十进制整数(小于65535),将其转换为二进制数,转换结果存在AX寄存器中。

1到n的循环求和汇编

1到n的循环求和汇编

1到n的循环求和汇编汇编语言是一种低级编程语言,用于编写计算机程序。

在汇编语言中,我们可以使用循环来实现一系列操作,例如求和。

本文将介绍如何使用汇编语言来实现1到n的循环求和。

我们需要定义一个变量n,它表示求和的上限。

我们可以使用汇编语言中的数据定义指令来声明这个变量,并给它赋初值。

例如,我们可以使用指令`MOV AX, n`来将变量n的值存储在寄存器AX中。

接下来,我们需要初始化一个累加器,用于存储求和的结果。

我们可以使用指令`MOV BX, 0`将累加器的初值设为0。

然后,我们可以使用循环指令来实现求和的过程。

在汇编语言中,有多种循环指令可供选择,例如`LOOP`指令、`JNZ`指令等。

这些指令可以根据条件来控制循环的执行次数。

在这个例子中,我们可以使用`LOOP`指令来实现循环求和。

循环求和的思路是不断将计数器的值加到累加器上,直到计数器的值达到上限。

我们可以使用指令`ADD BX, AX`将计数器的值加到累加器上。

然后,我们可以使用指令`DEC AX`将计数器的值减1。

最后,我们可以使用指令`CMP AX, 0`来判断计数器的值是否为0,如果不为0,则继续执行循环。

当循环结束后,累加器的值就是1到n的和。

我们可以使用指令`MOV n, BX`将累加器的值存储回变量n中。

下面是完整的汇编代码示例:```DATA SEGMENTn DW 10 ; 变量n,表示求和的上限sum DW 0 ; 累加器,用于存储求和的结果DATA ENDSCODE SEGMENTSTART:MOV AX, @DATA ; 初始化数据段寄存器MOV DS, AXMOV AX, n ; 将变量n的值存储在寄存器AX中 MOV BX, 0 ; 初始化累加器LOOP_START:ADD BX, AX ; 将计数器的值加到累加器上DEC AX ; 计数器减1CMP AX, 0 ; 判断计数器的值是否为0JNZ LOOP_START ; 如果不为0,则继续循环MOV sum, BX ; 将累加器的值存储回变量n中MOV AX, 4C00H ; 程序结束指令INT 21HCODE ENDSEND START```在上面的代码中,我们使用了数据段和代码段来分隔数据和代码。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验名称——累加
实验人:班级:
学号:课程:汇编语言
目的:掌握循环程序设计与过程的设计方法
内容:求出1到n的累加
设计思想:这个程序的设计从结构上来看主要分为三部分——1,键盘输入的数字字符串(十进制数值)如何变为具有数值意义的二进制数2,利用一个循环结构将1到n的和求出3,将一个就有数值意义的二进制数转化为ASCII码并以字符串(十进制)显示出来(与计算结果的二进制数相等)。

Array

.MODEL SMALL
.STACK 1024
.DATA
f1 db 'INPUT N:','$'
f3 db 0dh,0ah,'error','$'
p dw 0
sum dw 0
.CODE
.STARTUP
mov dx,offset f1
mov ah,9h ;显示字符input n:
int 21h
input:mov ah,1
int 21h ;显示输入字符并将字符的ascii值放入al cmp al,0dh
jz next
cmp al,'0'
jb next1
cmp al,'9' ;判断字符的合法性
ja next1
sub al,'0' ;将ascii码转化为每一位的数值mov ah,0
push ax ;通过堆栈保护数据
mov ax,p ;
shl ax,1
push ax
mov cl,2
shl ax,cl ;ax的值乘以4
xor bx,bx
pop bx
add ax,bx
xor bx,bx
pop bx
add ax,bx
mov p,ax ;将n的二进制数值存入p中
jmp input
next:mov bx,0 ;bx清零
xor ax,ax ;ax清零
mov cx,p ;循环次数存入cx中
again:inc bx
add ax,bx
loop again ;将n的累加求出并放入ax中
mov sum,ax ;将n的累加存入变量sum
loop1:mov dx,0 ;
mov bx,10
div bx
add dx,'0' 将要显示的数转化为ascii码
push dx ;通过堆栈保护数据
inc cx ;记录要显示字符的个数
cmp ax,0h ;判断商是否为零
jnz loop1
mov dx,offset info2
mov ah,9
int 21h ;这三步换行显示字符
loop2:pop dx ;将要显示的字符的ascii码放入dx mov ah,2
int 21h ;dos的2号调用显示字符
loop loop2 ;通过循环显示字符串
jmp next2 ;
next1:mov dx,offset info3
mov ah,9
int 21h
next2:
.EXIT
END
在这个程序的编写过程中收获了很多,如:如何将数值ascii 码转化为二进制数,循环结构的应用,将二进制数如何以十进制数值ascii码显示。

在此过程也了解到了堆栈的重要性,而且还有关于dos的调用。

这个程序的编写使我受益匪浅。

但是在调试的过程中也走了不少弯路,一开始就拿课件上的程序组合在一起,自以为还可以,在调试的过程中不时就出现乱码,还有那个换行显示,一开始显示的字符不在同一行。

反正就是显示错位,一看这情况真的很烦,但是到最后成功的时候真的很开心,前面的付出都是值得的。

一开始对汇编真的不太感兴趣,但是通过这个程序的编写后,发现自己真的爱上汇编了。

相关文档
最新文档