关于一个汇编程序的问题
1、dos功能调用的2、9号功能执行后,都要返回一个值给AL,这样,等到要显示数字或字母的ASCII码的时候,AL的值已经不是那个正确的值了。所以,应该先把AL保护起来。
2、这个程序不可能通过编译。只是OUTPUT_CHAR子程序中的
SHR BL,4
这一条指令,就会出错。超过1位的移位指令,移位次数要放在CL寄存器里。
DSEG SEGMENT
BUF0 DB 'INPUT AGAIN PLEASE!',0AH,0DH,'$'
M DB ?
N DB ?
FLAG DB ?
BUF DB ?
DSEG ENDS
CSEG SEGMENT
ASSUME DS:DSEG,CS:CSEG
START: MOV AX,DSEG
MOV DS,AX
;
BEGIN: MOV N,0
LEA SI,BUF
NEXT: MOV AH,1
INT 21H
CMP AL,'='
JZ EA
MOV [SI],AL
INC SI
INC N
JMP NEXT
EA: DEC N
CMP BYTE PTR[SI-1],'Q'
JNZ EC
LEA DI,BUF
EB: CMP BYTE PTR[DI],'Q'
JZ P1
CMP BYTE PTR[DI],30H
JB EI
CMP BYTE PTR[DI],37H
JA EI
INC DI
JMP EB
P1: CALL SUB1
JMP OK
EC: CMP BYTE PTR[SI-1],'B'
JNZ EE
LEA DI,BUF
ED: CMP BYTE PTR[DI],'B'
JZ P2
CMP BYTE PTR[DI],30H
JB EI
CMP BYTE PTR[DI],31H
JA EI
INC DI
JMP ED
P2: CALL SUB2
JMP OK
EE: CMP BYTE PTR[SI-1],'D'
JNZ EG
LEA DI,BUF
EF: CMP BYTE PTR[DI],'D'
JZ P3
CMP BYTE PTR[DI],30H
JB EI
CMP BYTE PTR[DI],39H
JA EI
INC DI
JMP EF
P3: CALL SUB3
JMP OK
EG: CMP BYTE PTR[SI-1],'H'
JNZ EI
LEA DI,BUF
EH: CMP BYTE PTR[DI],'H'
JZ P4
CMP BYTE PTR[DI],30H
JB EI
CMP BYTE PTR[DI],39H
JBE WW
CMP BYTE PTR[DI],'A'
JB EI
CMP BYTE PTR[DI],'F'
JA EI
WW: INC DI
JMP EH
P4: CALL SUB4
JMP OK
EI: LEA DX,BUF0
MOV AH,9
INT 21H
JMP BEGIN
OK: MOV AH,4CH
INT 21H
;
SUB1 PROC
LEA DI,BUF
CMP N,3
JA EI
JB MA
MOV AL,[DI]
AND AL,0FH
CMP AL,3
JBE QQ
JMP EI
QQ: MOV CL,6
SHL AL,CL
MOV BL,[DI+1]
AND BL,0FH
MOV CL,3
SHL BL,CL
OR AL,BL
MOV BL,[DI+2]
AND BL,0FH
OR BL,AL
JMP MC
MA: CMP N,2
JB MB
MOV AL,[DI]
AND AL,0FH
MOV CL,3
SHL AL,CL
MOV BL,[DI+1]
AND BL,0FH
OR BL,AL
JMP MC
MB: MOV BL,[DI]
AND BL,0FH
MC: MOV M,BL
; M中放八进制数拼接后的二进制
CALL SUB5
MOV DL,'='
MOV AH,2
INT 21H ;输出二进制
;
CALL SUB7
MOV DL,'='
MOV AH,2
INT 21H ;输出十进制
;
CALL SUB8 ;输出十六进制
;
RET
SUB1 ENDP
; ;输入八进制显示其它相应的进制
SUB2 PROC
CMP N,8
JBE MD
JMP EI
MD: LEA DI,BUF
MOV CH,0
MOV CL,N
MOV BL,0
ER: MOV AL,[DI]
AND AL,0FH
RCL AL,CL
RCR AL,1
OR BL,AL
INC DI
LOOP ER
MOV M,BL
; M中放二进制数拼接后的二进制
CALL SUB6
MOV DL,'='
MOV AH,2
INT 21H ;输出八进制
;
CALL SUB7
MOV DL,'='
MOV AH,2
INT 21H ;输出十进制
;
CALL SUB8 ;输出十六进制
;
RET
SUB2 ENDP
; 输入二进制显示其它相应的进制
SUB3 PROC
LEA DI,BUF
CMP N,4
JB ME
JMP EI
ME: CMP N,3
JB MF
MOV DL,100
MOV AH,0
MOV AL,[DI]
AND AL,0FH
MUL DL
MOV BX,AX
MOV DL,10
MOV AH,0
MOV AL,[DI+1]
AND AL,0FH
MUL DL
ADD BX,AX
MOV AH,0
MOV AL,[DI+2]
AND AL,0FH
ADD BX,AX
JMP MH
MF: CMP N,2
JB MG
MOV DL,10
MOV AH,0
MOV AL,[DI]
AND AL,0FH
MUL DL
MOV BX,AX
MOV AH,0
MOV AL,[DI+1]
AND AL,0FH
ADD BX,AX
JMP MH
MG: MOV BH,0
MOV BL,[DI]
AND BL,0FH
MH: CMP BX,0FFH
JBE NN
JMP EI
NN: MOV M,BL
; M中放十进制数拼接后的二进制
CALL SUB5
MOV DL,'='
MOV AH,2
INT 21H ;输出二进制
;
CALL SUB6
MOV DL,'='
MOV AH,2
INT 21H ;输出八进制
;
CALL SUB8 ;输出十六进制
;
RET
SUB3 ENDP
; 输入十进制显示其它相应的进制
SUB4 PROC
LEA DI,BUF
CMP N,3
JB MI
JMP EI
MI: CMP N,2
JB MK
MOV AL,[DI]
CMP AL,41H
JB LA
SUB AL,39H
ADD AL,2
JMP LB
LA: AND AL,0FH
LB: MOV CL,4
SHL AL,CL
MOV BL,AL
MOV AL,[DI+1]
CMP AL,41H
JB LC
MJ: SUB AL,39H
ADD AL,2
JMP LD
LC: AND AL,0FH
JMP LD
MK: MOV BL,0
MOV AL,[DI]
CMP AL,41H
JB LC
JMP MJ
LD: OR BL,AL
MOV M,BL
; M中放十六进制数拼接后的二进制
CALL SUB5
MOV DL,'='
MOV AH,2
INT 21H ;输出二进制
;
CALL SUB6
MOV DL,'='
MOV AH,2
INT 21H ;输出八进制
;
CALL SUB7 ;输出十进制
;
RET
SUB4 ENDP
; ;输入十六进制显示其它相应的进制
SUB5 PROC
MOV CX,1
MOV DL,M
CMP M,0
JZ LF
MOV FLAG,0
MOV CX,8
EJ: MOV DL,M
RCL DL,1
RCR DL,CL
AND DL,1
CMP DL,0
JNZ LF
CMP FLAG,0
JZ LG
LF: OR DL,30H
MOV AH,2
INT 21H
MOV FLAG,1
LG: LOOP EJ
MOV DL,'B'
MOV AH,2
INT 21H
RET
SUB5 ENDP
; 把M中的二进制数显示
SUB6 PROC
MOV DL,M
MOV CL,6
SHR DL,CL
CMP DL,0
JZ EM
OR DL,30H
MOV AH,2
INT 21H
MOV FLAG,1
EM: MOV DL,M
MOV CL,3
SHR DL,CL
AND DL,7
CMP DL,0
JNZ LR
CMP FLAG,0
JZ LS
LR: OR DL,30H
MOV AH,2
INT 21H
LS: MOV DL,M
AND DL,7
OR DL,30H
MOV AH,2
INT 21H
MOV DL,'Q'
MOV AH,2
INT 21H
RET
SUB6 ENDP
; 把M以八进制数显示
SUB7 PROC
MOV AH,0
MOV AL,M
MOV CL,100
DIV CL
MOV DX,AX
CMP DL,0
JZ EK
OR DL,30H
MOV AH,2
INT 21H
MOV FLAG,1
EK: MOV AH,0
MOV AL,DH
MOV CL,10
DIV CL
MOV DX,AX
CMP DL,0
JNZ LH
CMP FLAG,0
JZ LI
LH: OR DL,30H
MOV AH,2
INT 21H
LI: MOV DL,DH
OR DL,30H
MOV AH,2
INT 21H
MOV DL,'D'
MOV AH,2
INT 21H
RET
SUB7 ENDP
; 把M以十进制数显示
SUB8 PROC
MOV CL,4
MOV DH,2
EL: MOV DL,M
SHR DL,CL
AND DL,0FH
CMP DL,9
JA A
OR DL,30H
JMP H
A: SUB DL,9
ADD DL,40H
H: MOV AH,2
INT 21H
SUB CL,4
DEC DH
JNZ EL
MOV DL,'H'
MOV AH,2
INT 21H
RET
SUB8 ENDP
; 把M以十六进制数显示
CSEG ENDS
END START
呵呵
data segment
org 2000h
str1 db 'Aedc123!*sdeDIO71$'
count equ $-str1
org 3000h
str2 db 0dh,0ah,count dup(?)
data ends
code segment
assume cs:code,ds:data
start proc far
push ds
mov ax,0
push ax
mov ax,data
mov ds,ax
lea si,str1
lea di,str2
add di,2
start1:
mov al,[si]
cmp al,'$'
je start3
cmp al,61h ;应该和SI指向的内存单元中的内容比较
jb start2;小于'a'则进行下一个字符判断
cmp al,7Ah
ja start2;大于'z'则进行下一个字符判断
sub al,20h ;将小写转换为大写
start2:
mov [di],al
inc di
inc si;调整SI指向下一个字符
jmp start1;循环处理所有字符
start3:
mov byte ptr [di],'$'
lea dx,str1;输出源串
mov ah,9h
int 21h
lea dx,str2;输出转换后的目的串
mov ah,9h
int 21h
mov ah,1
int 21h
ret
start endp
code ends
end start
给修改了部分指令,参照、对比一下。
stack segment para stack 'stack'
db 100 dup(?)
stack ends
data segment
org 2000h
str1 db 'Aedc123!*sdeDIO71$'
count equ $-str1
org 3000h
str2 db count dup(?)
data ends
code segment
assume cs:code,ds:data
start proc far
push ds
mov ax,0
push ax
mov ax,data
mov ds,ax
mov es,ax
lea si,str1
lea di,str2
mov cx,count
cld
start1:lodsb
cmp al,'a'
jb next
cmp al,'z'
ja next
and al,0dfh
next:stosb
loop start1
lea dx,str1
mov ah,9h
int 21h
mov dl,13
mov ah,2
int 21h
mov dl,10
int 21h
lea dx,str2
mov ah,9h
int 21h
ret
start endp
code ends
end start
请教一个汇编问题,刚开始学习汇编。求大神赐教
汇编器在给段分配空间的时候,是按照16字节大小来分配的,N\/16取整之后分配了N\/16个16字节的空间,余数部分的数据需要再分配一个16字节的空间,所以结果便是:(N\/16 +1)*16。
汇编语言 程序问题
下列程序,经过检验,符合条件要求。DATA SEGMENT BUFFER DB 80 DUP(?)DATA ENDS ;--- CODE SEGMENT ASSUME CS:CODE, DS:DATA START:MOV AX, DATA MOV DS, AX ;--- MOV BX, OFFSET BUFFER MOV AH, 1 INT 21H CMP AL, ' ' ;和空格相比较.JNZ EXIT ;不相等就退出...
自己写的单片机实验汇编程序,问题:灯不亮! 麻烦指出错误,最好改一下...
MAIN: MOV P1,#07FH MOV P3,#0EFH;错误,应将P3.4置高。注意51的IO口是准双向口,内部只有弱上拉,和强下拉,置低后外部不能将它拉高。INT01: PUSH PSW PUSH ACC ALARM: MOV P1,#0FFH RING: MOV R2,#50 CPL P1.7;取反 SETB P1.7;这句多余了,DJNZ R2,RING JNB P3.3,...
关于汇编语言一个问题
16位汇编语言中,物理地址=段地址*16(即16进制的10H,亦即二进制中左移4位,或16进制中左移一位)+偏移地址,构成20位地址(因为8086CPU有20位地址线)。所以此题的PA=DS*16+1352H=10000+1352=11352H(通常表示成 1000:1352 的形式)。而指令MOV AX,[1352H] 即是将地址1000:1352H(默认段...
一个关于汇编语言的问题?
EQU是表达式赋值操作符(伪指令),在这里 LED等价于P0,NUM等价于地址18H,当然自己可以随便定义,比如把LED改成AAA,需要自己记得其意义。在以后的程序中出现使用P0时,直接用LED,使用18H时用NUM,增加程序可读性和易修改性。
汇编语言问题:编写程序,找出一个子数组中最小的偶数
MOV BX,0LOOP1:MOV AX,buffer[BX]TEST AX,01H JNZ JISHU1 JZ nextJISHU1:cmp ax,mix jl mixjishu jnl next mixjishu:MOV mix,AXnext:ADD BX,2 DEC DI JNE LOOP1 RET JISHU_PROC ENDP bin_dec proc near ;子程序bin_dec输出 push bx push cx push si push di mov cx,100 call ...
帮我解决一个汇编语言的题目。。。3Q
2.题目要求:要找出数字5的ASCII码的...答案中,却是用31h来进行判别,这是1的ASCII码。3.题目要求:码表中的第一个单元存放着码表的长度,...答案中,只有一些ASCII码,并没有长度。问东答西!回答问题,应该实事求是。启发性的回答,当然好,但是就别说“这是最后运行成功的源程序”。这不是...
初学汇编,请回答一个问题
存储器是20位物理地址,但寄存器只有16位,所以内存被分段管理,这样有编程时就用段地址:偏移地址的形式来表示内存单元。其中段地址是一个的首地址,用段寄存器CS、DS、ES、SS来表示;而偏移地址(也叫有效地址EA)则表示离段首地址有多远的偏移量,编程时可以用寄存器BX、BP、SI、DI来存储,也可以...
有关于汇编语言的问题?
但是如果结果超过存储器位数,那么结果就不等于两个操作数相加,这时候相当于向高位进位。上面都是针对无符号数而言。SBB指令特殊的地方,是被减数除了减去减数之外,还要减去CF,比如:SBB AX,BX 如果AX=20 BX=10 CF=1,则这个指令的结果是 AX=AX-BX-CF=9 执行完之后,CF设置为0表示没有借位 ...
51单片机汇编语言的一个小问题
就是对两位压缩BCD码进行调整 比如r1 = 17h a = 28h add a,r1 显然 a=3fh 但是 这不是我们想要的结果,因为我们用一个字节表示的是压缩的BCD码,而bcd码根据8421的标准码是么有f这个数字的,虽然里面存的数据是17h和28h 但是我们把他看成是bcd码,也就是说用4位数字表示一个数,17h+...
店旭盐酸: 首先,这是汇编语言的规定;其次,这个规定也是有道理的.COSEG ENDS和COSEG SEGMENT成对出现,其间的内容主要是各种指令和伪指令,表示这是一个代码段,而不是其它的段.其中,COSEG是这个代码段的段名,只要符合汇编语言关于标识符的规定,这个段名由编程者随意命名.而END START 只是告诉汇编编译器,编译到此为止,下面的内容与本程序无关.概念不一样的.
平和县13151163907: 关于一个汇编程序的问题 - ?
店旭盐酸: 下列代码是完成将以$结束的字符串中的小写字母改为大写字母,而其它字符保持不变的功能.data segment org 2000h str1 db 'Aedc123!*sdeDIO71$' count equ $-str1 org 3000h str2 db 0dh,0ah,count dup(?) data ends code segment assume cs:...
平和县13151163907: 一个汇编程序的问题 高手指教 - ?
店旭盐酸: 1、总体评价 这个程序,结构清晰、层次分明,数据段中相关数据的定义也不错,从数据结构的设计来看,数据结构设计合理,是挺好的. 程序设计领域有句名言:数据结构+算法=程序 但从算法...
平和县13151163907: 汇编程序问题?
店旭盐酸: 简单说一下思路,你知道汇编写程序很麻烦的,实在没时间写.首先你得从键盘端口读入数据,读的时候注意整数部分和小数部分分开读,分割的标志当然就是小数点啦.读完后就简单了,整数部分和小数部分分别求和计算,比如1.12+5.34,分别算1+5=6,12+34=46,再合到一起中间加小数点就是结果6.46了,进位的问题也是可以处理的,因为小数部分不超过两位,所以你可以把小数部分都化为2位整数,一旦检测到结果超过100,就向整数部分进位就行了,如1.50+2.82,50+82=132,留下32做小数部分,进一位1+2+1=4.结果是4.32.总体就是这样,希望能对你有所帮助
平和县13151163907: 一个汇编程序的问题.?
店旭盐酸: 题目中明确说了,有L个字符,程序中也进行了L次循环的设定,如果没有空格,执行了L次LOOPNE NEXT后,就执行下一句:JNZ NOT-FOUND,从而跳到NOT-FOUND.
平和县13151163907: 有关于汇编语言的问题? - ?
店旭盐酸: 其实借位很容易理解,比如被减数 01001011 比 减数10000000小,减了结果肯定是负数,但CPU计算的时候仍然按正数算,怎么办,很简单,只需要给被减数的前面再加一个1,被减数就比减数大了,比如加1后被减数变为101001011,比减数...
平和县13151163907: 紧急求助:一个汇编程序的问题! - ?
店旭盐酸: FINISH: mov byte ptr [bx][1],'$' ;准备输出lea dx,stringmov ah,9int 21hret
平和县13151163907: 请教关于一个汇编程序段的问题…… - ?
店旭盐酸: 首先你要弄清楚MOVSB这条指令.他把指针DS:SI所指向的字节传送给指针ES:DI所指向内存单元,并根据标志位DF对寄存器DI和SI作相应增减.因为你的DATA1和DATA2的段地址相同,只是偏移不同,所以才有了这个操作.
平和县13151163907: 汇编程序的问题! - ?
店旭盐酸: 问题症结在于:mov sp,length buff 本来你定义了100个字的堆栈空间,但你用了长度属性操作符length,它返回数组变量的长度64H,而非容量0C8H.若要充分利用这100个字的堆栈空间,要用容量属性操作符SIZE,把上面那句改成:mov sp,SIZE buff 就正确了.至于不执行 mov ah,07h int 21h 想必是 mov ah,00h mov al,13h int 10h 需要较大的堆栈空间,而你定义的栈顶必然是小了.
平和县13151163907: 一个简单的汇编问题 - ?
店旭盐酸: 出栈后sp指针的值加2,所以sp=000CH+2=000EH 栈顶物理地址=ss*16+sp=00A80H+000EH=00A8EH 堆栈是先进后出、后进先出结构,基本单位是字(两个字节).所以,进栈(PUSH)的时候,堆栈指针(SP)减2,把数据(字)压入栈顶;出栈(POP)的时候,把数据弹出给指定的寄存器,堆栈指针加2.堆栈是一种数据结构,用SS表示堆栈的段地址、SP表示堆栈的偏移地址(栈顶),与堆栈指令(PUSH和POP)配合使用、紧密相连,这是汇编语言的规定.程序=数据结构+算法.