汇编语言程序设计

汇编语言程序设计,第1张

name "calc2"

; command prompt based simple calculator (+,-,,/) for 8086

; example of calculation:

; input 1 <- number: 10

; input 2 <- operator: -

; input 3 <- number: 5

; -------------------

; 10 - 5 = 5

; output -> number: 5

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; this maro is copied from emu8086inc ;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; this macro prints a char in AL and advances

; the current cursor position:

PUTC MACRO char

PUSH AX

MOV AL, char

MOV AH, 0Eh

INT 10h

POP AX

ENDM

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

org 100h

jmp start

; define variables:

msg0 db "note: calculator works with integer values only",0Dh,0Ah

db "to learn how to output the result of a float division see floatasm in examples",0Dh,0Ah,'$'

msg1 db 0Dh,0Ah, 0Dh,0Ah, 'enter first number: $'

msg2 db "enter the operator: + - / : $"

msg3 db "enter second number: $"

msg4 db 0dh,0ah , 'the approximate result of my calculations is : $'

msg5 db 0dh,0ah ,'thank you for using the calculator! press any key ', 0Dh,0Ah, '$'

err1 db "wrong operator!", 0Dh,0Ah , '$'

smth db " and something $"

; operator can be: '+','-','','/' or 'q' to exit in the middle

opr db ''

; first and second number:

num1 dw

num2 dw

start:

mov dx, offset msg0

mov ah, 9

int 21h

lea dx, msg1

mov ah, 09h ; output string at ds:dx

int 21h

; get the multi-digit signed number

; from the keyboard, and store

; the result in cx register:

call scan_num

; store first number:

mov num1, cx

; new line:

putc 0Dh

putc 0Ah

lea dx, msg2

mov ah, 09h ; output string at ds:dx

int 21h

; get operator:

mov ah, 1 ; single char input to AL

int 21h

mov opr, al

; new line:

putc 0Dh

putc 0Ah

cmp opr, 'q' ; q - exit in the middle

je exit

cmp opr, ''

jb wrong_opr

cmp opr, '/'

ja wrong_opr

; output of a string at ds:dx

lea dx, msg3

mov ah, 09h

int 21h

; get the multi-digit signed number

; from the keyboard, and store

; the result in cx register:

call scan_num

; store second number:

mov num2, cx

lea dx, msg4

mov ah, 09h ; output string at ds:dx

int 21h

; calculate:

cmp opr, '+'

je do_plus

cmp opr, '-'

je do_minus

cmp opr, ''

je do_mult

cmp opr, '/'

je do_div

; none of the above

wrong_opr:

lea dx, err1

mov ah, 09h ; output string at ds:dx

int 21h

exit:

; output of a string at ds:dx

lea dx, msg5

mov ah, 09h

int 21h

; wait for any key

mov ah, 0

int 16h

ret ; return back to os

do_plus:

mov ax, num1

add ax, num2

call print_num ; print ax value

jmp exit

do_minus:

mov ax, num1

sub ax, num2

call print_num ; print ax value

jmp exit

do_mult:

mov ax, num1

imul num2 ; (dx ax) = ax num2

call print_num ; print ax value

; dx is ignored (calc works with tiny numbers only)

jmp exit

do_div:

; dx is ignored (calc works with tiny integer numbers only)

mov dx, 0

mov ax, num1

idiv num2 ; ax = (dx ax) / num2

cmp dx, 0

jnz approx

call print_num ; print ax value

jmp exit

approx:

call print_num ; print ax value

lea dx, smth

mov ah, 09h ; output string at ds:dx

int 21h

jmp exit

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; these functions are copied from emu8086inc ;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; gets the multi-digit SIGNED number from the keyboard,

; and stores the result in CX register:

SCAN_NUM PROC NEAR

PUSH DX

PUSH AX

PUSH SI

MOV CX, 0

; reset flag:

MOV CS:make_minus, 0

next_digit:

; get char from keyboard

; into AL:

MOV AH, 00h

INT 16h

; and print it:

MOV AH, 0Eh

INT 10h

; check for MINUS:

CMP AL, '-'

JE set_minus

; check for ENTER key:

CMP AL, 0Dh ; carriage return

JNE not_cr

JMP stop_input

not_cr:

CMP AL, 8 ; 'BACKSPACE' pressed

JNE backspace_checked

MOV DX, 0 ; remove last digit by

MOV AX, CX ; division:

DIV CS:ten ; AX = DX:AX / 10 (DX-rem)

MOV CX, AX

PUTC ' ' ; clear position

PUTC 8 ; backspace again

JMP next_digit

backspace_checked:

; allow only digits:

CMP AL, '0'

JAE ok_AE_0

JMP remove_not_digit

ok_AE_0:

CMP AL, '9'

JBE ok_digit

remove_not_digit:

PUTC 8 ; backspace

PUTC ' ' ; clear last entered not digit

PUTC 8 ; backspace again

JMP next_digit ; wait for next input

ok_digit:

; multiply CX by 10 (first time the result is zero)

PUSH AX

MOV AX, CX

MUL CS:ten ; DX:AX = AX10

MOV CX, AX

POP AX

; check if the number is too big

; (result should be 16 bits)

CMP DX, 0

JNE too_big

; convert from ASCII code:

SUB AL, 30h

; add AL to CX:

MOV AH, 0

MOV DX, CX ; backup, in case the result will be too big

ADD CX, AX

JC too_big2 ; jump if the number is too big

JMP next_digit

set_minus:

MOV CS:make_minus, 1

JMP next_digit

too_big2:

MOV CX, DX ; restore the backuped value before add

MOV DX, 0 ; DX was zero before backup!

too_big:

MOV AX, CX

DIV CS:ten ; reverse last DX:AX = AX10, make AX = DX:AX / 10

MOV CX, AX

PUTC 8 ; backspace

PUTC ' ' ; clear last entered digit

PUTC 8 ; backspace again

JMP next_digit ; wait for Enter/Backspace

stop_input:

; check flag:

CMP CS:make_minus, 0

JE not_minus

NEG CX

not_minus:

POP SI

POP AX

POP DX

RET

make_minus DB ; used as a flag

SCAN_NUM ENDP

; this procedure prints number in AX,

; used with PRINT_NUM_UNS to print signed numbers:

PRINT_NUM PROC NEAR

PUSH DX

PUSH AX

CMP AX, 0

JNZ not_zero

PUTC '0'

JMP printed

not_zero:

; the check SIGN of AX,

; make absolute if it's negative:

CMP AX, 0

JNS positive

NEG AX

PUTC '-'

positive:

CALL PRINT_NUM_UNS

printed:

POP AX

POP DX

RET

PRINT_NUM ENDP

; this procedure prints out an unsigned

; number in AX (not just a single digit)

; allowed values are from 0 to 65535 (FFFF)

PRINT_NUM_UNS PROC NEAR

PUSH AX

PUSH BX

PUSH CX

PUSH DX

; flag to prevent printing zeros before number:

MOV CX, 1

; (result of "/ 10000" is always less or equal to 9)

MOV BX, 10000 ; 2710h - divider

; AX is zero

CMP AX, 0

JZ print_zero

begin_print:

; check divider (if zero go to end_print):

CMP BX,0

JZ end_print

; avoid printing zeros before number:

CMP CX, 0

JE calc

; if AX<BX then result of DIV will be zero:

CMP AX, BX

JB skip

calc:

MOV CX, 0 ; set flag

MOV DX, 0

DIV BX ; AX = DX:AX / BX (DX=remainder)

; print last digit

; AH is always ZERO, so it's ignored

ADD AL, 30h ; convert to ASCII code

PUTC AL

MOV AX, DX ; get remainder from last div

skip:

; calculate BX=BX/10

PUSH AX

MOV DX, 0

MOV AX, BX

DIV CS:ten ; AX = DX:AX / 10 (DX=remainder)

MOV BX, AX

POP AX

JMP begin_print

print_zero:

PUTC '0'

end_print:

POP DX

POP CX

POP BX

POP AX

RET

PRINT_NUM_UNS ENDP

ten DW 10 ; used as multiplier/divider by SCAN_NUM & PRINT_NUM_UNS

GET_STRING PROC NEAR

PUSH AX

PUSH CX

PUSH DI

PUSH DX

MOV CX, 0 ; char counter

CMP DX, 1 ; buffer too small

JBE empty_buffer ;

DEC DX ; reserve space for last zero

;============================

; Eternal loop to get

; and processes key presses:

wait_for_key:

MOV AH, 0 ; get pressed key

INT 16h

CMP AL, 0Dh ; 'RETURN' pressed

JZ exit_GET_STRING

CMP AL, 8 ; 'BACKSPACE' pressed

JNE add_to_buffer

JCXZ wait_for_key ; nothing to remove!

DEC CX

DEC DI

PUTC 8 ; backspace

PUTC ' ' ; clear position

PUTC 8 ; backspace again

JMP wait_for_key

add_to_buffer:

CMP CX, DX ; buffer is full

JAE wait_for_key ; if so wait for 'BACKSPACE' or 'RETURN'

MOV [DI], AL

INC DI

INC CX

; print the key:

MOV AH, 0Eh

INT 10h

JMP wait_for_key

;============================

exit_GET_STRING:

; terminate by null:

MOV [DI], 0

empty_buffer:

POP DX

POP DI

POP CX

POP AX

RET

GET_STRING ENDP

分类: 电脑/网络 >> 程序设计 >> 其他编程语言

问题描述:

31. MOV DL,AL

NOT DL

TEST DL,04H

JE NEXT

NEXT:…

若上述程序段执行时产生分支,说明AL中的数第几位一定为1?程序段执行后CF是多少?

32.DA1 DB‘ABCDEFGHI’

DA2 DB 9 DUP(0)

LEA SI,DA1

LEA DI,DA2

MOV CX,9

CLD

LOP: LODSB

SUB AL,10H

STOSB

LOOP LOP

试问:①写出程序执行后DA2各字节中的数据。

②保持程序功能情况下,程序中 可否改写为

33.已知:BX=4567H

NEG BX

INC BX

NEG BX

DEC BX

程序段执行后,BX=________,CF=________。

34. MOV BL,64H

MOV CL,03H

XOR AX,AX

AGAIN:ADD AL,BL

ADC AH,0

DEC CL

JNZ AGAIN

问:(1)该程序段完成的功能是:

(2)AX=________。

35.已知数据段中定义

DAT1 DB 12H,34H,56H,78H

MOV CX,0

MOV AX,WORD PTR DAT1

MOV CL,DAT1+3

当程序段执行完后AX=________,CX=________。

36.DA1 DB 83H,72H,61H,94H,5AH

MOV CX,WORD PTR DA1

AND CX,0FH

MOV AL,DA1+3

SHL AL,CL

上述指令序列执行后,AL=_______,CL=_______。

解析:

31.从第0位开始数的第2位一定为1;CF=0

32.

①""

②保持程序功能情况下,程序中 可否改写为 ——什么呀,题目都不完整

33.BX=4564H,CF=1

34.

(1)100+100+100

(2)AX=012CH

35.AX=3412H,CX=0078H

36.AL=0A0H,CL=3

汇编语言程序设计的基本步骤 了解了汇编语言指令的功能和用法,了解了汇编语言程序的编写格式,就可以编制完整的汇编语言程序了。一个程序通常具有顺序、分支、循环和子程序4种结构形式。顺序程序结构就是指完全按顺序逐条执行的指令序列。在程序设计过程中,顺序结构大量存在,屡见不鲜。但一个完整的程序只是逐条去执行指令,这非常少见。常见的程序结构,是上述4种结构的混合体。一般来说,编制一个汇编语言程序的步骤如下:(1) 分析题意,确定算法或算法思想。算法是指解决问题的方法和步骤。比如现有的一些计算方法和日常生活中解决问题的逻辑思维推理方法等。(2) 根据算法画出流程图,简单的情况也可不画。画出描述算法的流程图,可以首先从图上检验算法的正确性,减少出错的可能,使得动手编写程序时的思路更加清晰。(3) 分配存储空间和工作单元,合理地使用寄存器。分配存储空间和工作单元,是指存储空间的分段和数据定义。另外,由于寄存器的数量有限,编写程序时经常会感到寄存器不够用。因此,对于字节数据,要尽量使用8位寄存器。而采用适当的寻址方式,也会达到节省寄存器的目的。(4) 根据流程图编写程序。这是编制汇编语言程序最为重要的一步。算法里规定的功能,是要通过一条条指令描述出来的。为了提高编程能力,对于初学者,一是要多阅读现有的程序,以学习别人的编程经验;而更为重要的是,必须多亲自动手编写,不要怕失败,只有通过无数次失败,才能从中积累自己的编程经验。(5) 上机调试运行程序。通过汇编的源程序,只能说明它里面不存在语法错误。但是它是否能达到算法所要求的预期效果,还必须经过上机调试,用一些实验数据来测试,才能够真正地得出结论。可以这么说,即使是一个非常有经验的程序员,也没有百分之百的把握说他编写的程序一次就成功。 用流程图表示算法 流程图用一些图形框来代表各种 *** 作。用图形表示算法,直观形象,可以用来帮助人们对算法的理解。下图给出了一些常用的流程图符号。

上图中的判断框(菱形)用来对一个给定的条件作出判断,以决定如何执行其后的 *** 作。它有一个入口,两个出口,如下图(a)所示。

连接点(圆圈)是用来将画在不同地方的流程线连接起来。例如在下图(b)里,有两个圈里写着数字1的圆圈,它表示是从左边的1出来,进到右边图的1里(这由流程线的方向给出)。可以看出,这两个点其实就是同一个点,只是由于画不下而分开来画的。用连接点,可以避免流程图中的流程线相互交叉或过长,从而使流程图清晰。

注释框不是流程图中必需的部分。在流程图中使用它,是为了对流程图中的某些框的 *** 作做一些必要的说明,以便使人们能够更好地通过流程图来理解算法。

处理框反映做些什么样的 *** 作,如把某个单元的内容送入某个寄存器,从某个存储单元取出数据等。它是流程图里最为本质的、出现最多的图形框。

输入/输出框反映程序的输入和输出情况。计算机程序无外乎接收数据,进行处理,然后加以输出,所以输入/输出框是必不可少的。

编码不容易,望能帮到楼主。楼主好好看

CRLFMACRO;宏定义,实现回车换行

MOVAH,2

MOVDL,0DH

INT21H

MOVAH,2

MOVDL,0AH

INT21H

ENDM

DSEGMENT

SCOREDB76,69,84,90,73,88,89,63,100,80;数组接收分数

SDB5DUP();预留5个位置存储每个分数段的人数

WORDSDB"THENUMBERBETWEEN60~69IS:$"

WORDS1DB"THENUMBERBETWEEN70~79IS:$"

WORDS2DB"THENUMBERBETWEEN80~89IS:$"

WORDS3DB"THENUMBERBETWEEN90~99IS:$"

WORDS4DB"THENUMBERBETWEEN100IS:$"

DENDS

CODESEGMENT

ASSUMECS:CODE,DS:D

BG:

MOVAX,D

MOVDS,AX

CALLCOUNT;调用子程序

MOVAH,9;输出每个分数段的人数

LEADX,WORDS

INT21H

MOVAH,2

MOVDL,S

ADDDL,30H

INT21H

CRLF

MOVAH,9

LEADX,WORDS1

INT21H

MOVAH,2

MOVDL,S1

ADDDL,30H

INT21H

CRLF

MOVAH,9

LEADX,WORDS2

INT21H

MOVAH,2

MOVDL,S2

ADDDL,30H

INT21H

CRLF

MOVAH,9

LEADX,WORDS3

INT21H

MOVAH,2

MOVDL,S3

ADDDL,30H

INT21H

CRLF

MOVAH,9

LEADX,WORDS4

INT21H

MOVAH,2

MOVDL,S4

ADDDL,30H

INT21H

CRLF

MOVAH,4CH

INT21H

COUNT:;子程序入口

MOVCX,10;循环10次

MOVSI,0

LOP:

INT3

MOVAL,SCORE[SI]

CMPAL,70

JBNUMBER6;比较进入不同的标号进行计算每个分数段人数

CMPAL,80

JBNUMBER7

CMPAL,90

JBNUMBER8

CMPAL,100

JENUMBER10

JMPNUMBER9

NUMBER6:;不同标号之下的作用是计算每个分数段人数并存于预留的位置中

MOVBL,S

INCBL

MOVS,BL

JMPL

NUMBER7:

MOVBL,S1

INCBL

MOVS1,BL

JMPL

NUMBER8:

MOVBL,S2

INCBL

MOVS2,BL

JMPL

NUMBER9:

MOVBL,S3

INCBL

MOVS3,BL

JMPL

NUMBER10:

MOVBL,S4

INCBL

MOVS4,BL

JMPL

L:

INCSI

LOOPLOP

RET;子程序结束,放回主程序

CODEENDS

ENDBG

汇编语言程序设计步骤:1、 分析问题,抽象出描述问题的数据模型 2、 确定问题的算法思想 3、 画出流程图或结构图 4、 分配存储器和工作单元(寄存器) 5、 逐条编写程序 6、 静态检查,上机调试 例:编程查找考生的最高分,假设所有考生分数已存入计算机内存1、 分析问题 根据条件、特点、规律 →数学模型 本例分数已给定为0~200之间的整数集合(考虑加试分) ,记为{S},找max{S}(注:简单问题不一定写数学模型) 2、 确定算法思想 最好利用现成算法和程序设计方法,若无,则需根据实践经验总结算法思想如本例,从成绩单第一分数往下看,边看边比较,记住较高分,舍弃较低分,直至看完,最高分存于 脑中归纳算法思想:建立数据指针并指向数据区首地址将第一数取入寄存器(如AL) ,与下一数比较,若下一数大则将其取入寄存器,否则调整指针,再与下一数比较,重复上述 直至比较完毕,寄存器中即最高分读分数用MOV指令,比较用CMP指令,分析判断用条件转移指令3、 画流程图或结构图 有逻辑流程、算法流程、程序流程等,复杂问题需画模块结构本例简单,只画出程序 流程图(用模块化结构的N-S流程图表示) :本例的N-S流程图 图中初始化包括:设一个计数器,将分数个数减一后送计数器,每比较一次减一,至 零查找结束;建立一个指针指向数据区开始 初始化 取第一数到寄存器 与下一数比较 下一数大是 否 取大数到寄存器 修改指针,计数次数减一 返回到循环体开始,直到计数次数为0退出循环 结束 4、 分配存储器空间和工作单元(寄存器) 定义数据段、堆栈段、代码段等工作单元一般用寄存器本例:分数放数据段,建100 字节堆栈空间,BX作数据指针,CX作计数器,AL放最高分5、 逐条编写程序 DATA SEGMENT FEN DB 85,90,60,75,87,35,80,78,96,82…… ;存分数 MAX DB ;存最高分 DATA ENDS STACK SEGMENT PARA STACK ‘STACK’ DB 100 DUP() ;100字节堆栈 STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK START PROC FAR PUSH DS MOV AX,0 PUSH AX ;为了返回DOS MOV AX,DATA MOV DS,AX ;置数据段寄存器 MOV BX,OFFSET FEN ;置数据指针 MOV CX,MAX-FEN ;置计数器初值 DEC CX ;N个分数比较N-1次 MOV AL,[BX] ;取第一个分数 LOP:INC BX ;调整指针 CMP AL,[BX] ;与下一数比较 JAE NEXT ;大于等于则转 MOV AL,[BX] ;否则取下一数 NEXT:LOOP LOP ;计数器减一,;不为零转LOP MOV MAX,AL ;存放最高分 RET ;返回DOS START ENDP CODE ENDS END START 6、 静态检查,上机调试 选用指令尽量字节少,使其执行速度快易错处应重点查,如比较次数、转移条件等确信无错后方可上机调试

以上就是关于汇编语言程序设计全部的内容,包括:汇编语言程序设计、高手请进,问汇编语言程序设计问题、汇编语言程序设计的一般步骤是什么等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/zz/9309034.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-27
下一篇2023-04-27

发表评论

登录后才能评论

评论列表(0条)

    保存