回复 9楼 Valenciax
咦?其实就是atoi函数,这就简单了。我想复杂了,还在考虑将输入转换为bcd码,还是不是要用什么aam、aad进行asc码调整,想到这些指令从未用过(其实以前写汇编算术运算最多无符号加减),就迟迟没动手了

最近真的事多,体制内的单位总是忙着搞半年度材料,很不幸地我就是那个写材料的最底层的那个。无暇写这些作业,容后再说了~~~~

能编个毛线衣吗?
程序代码:LeapYear: ;輸入AX=年份,輸出AX=1(閏年),AX=0(非閏年) push bx push dx push si mov si,ax mov bx,400 ;年份除以400餘數等于零,為閏年 mov dx,0 div bx or dx,dx ;是否0 jz last ;餘數為零,直接輸出閏年 mov dx,0 mov bx,4 ;除以400餘數不等于0,進行除以4餘數是否等0的判斷 mov ax,si div bx or dx,dx ;是否0 jz ok ;除以四餘數等于0,跳往除以100餘數是否等0的判斷 over: ;除以四餘數不等于0,則不為閏年,結束 mov ax,0 jmp nil ok: mov bx,100 ;除以100餘數為零,則不為閏年,餘數不為零,則為閏年 mov dx,0 mov ax,si div bx or dx,dx ;是否0 jz over last: mov ax,1 nil: pop si pop dx pop bx ret
程序代码: code segment
assume cs:code,ds:code,es:code,ss:code
org 100h
start: mov dx,offset buf1
mov si,offset buf1+2
mov ax,0c0ah
slp1: int 21h
mov ah,2
mov dl,10
int 21h
call atoi
or ax,ax
jz slp2
cmp ax,21845
ja slp2 ;数据合法性判断
slp5: cmp ax,max
jb slp6
mov max,ax ;得到最大数
slp6: mov bx,ax ;空出ax寄存器调int21用
call hexdec ;显示数据
cmp bx,1
jz slp3 ;最终数据是1,完成
inc word ptr step ;操作步数增1
mov dx,offset disp5
mov ah,9
int 21h ;显示->2361545863 余金平
mov cx,1
mov ax,bx
and cx,bx
jz slp4 ;转到对偶数的处理
mov cx,3
mul cx
inc ax
jmp slp5 ;*3+1
slp4: shr ax,1
jmp slp5 ;/2
slp3: mov dx,offset disp6
mov ah,9
int 21h ;回车换行
mov dx,offset disp2
int 21h ;Max is
mov ax,max
call hexdec ;显示最大数
mov ah,9
mov dx,offset disp3
int 21h ;and we need
mov ax,step
call hexdec ;显示总步数
mov ah,9
mov dx,offset disp4
int 21h ;steps.
jmp slp7
slp2: mov ah,9
mov dx,offset disp1 ;显示数据错误
int 21h
slp7: mov ax,4c00h
int 21h
atoi: ;本函数将asc串转换为16位int数,ds:si为asc串首,非数字转换结束,结果在ax中返回
push si
push bx
push cx
push dx
xor cx,cx
mov bx,10
ailp2: mov ax,cx
mul bx
jc ailp1
mov dx,ax
xor ax,ax
lodsb
sub al,'0'
cmp al,9
ja ailp1
mov cx,dx
add cx,ax
jmp ailp2
ailp1: mov ax,cx
pop dx
pop cx
pop bx
pop si
ret
hexdec: ;本函数将16进制数用十进制数形式显示出来,待显示的数在ax中
push bx
push cx
push dx
xor cx,cx
mov bx,10
hdlp1: xor dx,dx
div bx
add dl,'0'
push dx
inc cx
or ax,ax
jnz hdlp1
mov ah,2
hdlp2: pop dx
int 21h
loop hdlp2
pop dx
pop cx
pop bx
ret
buf1 db 20,0,20 dup(0)
max dw 0
step dw 0
disp1 db " Input Error! $"
disp2 db " Max is $"
disp3 db " and we need $"
disp4 db " steps.",13,10,'$'
disp5 db "->$"
disp6 db 13,10,'$'
code ends
end start

程序代码:
NLimit equ 999999999
code segment
assume cs:code,ds:code,es:code,ss:code
org 100h
start:jmp short begin
InputBuffer db 10,0,10 dup (0)
DispStr db 10,13,'Input a number (1-999,999,999):$'
CurrentValue dd 0
Step dd 0
MaxValue dd 0
Dispstr1 db 10,13,'Max is ','$'
Dispstr2 db ' and we need ','$'
Dispstr3 db ' steps.','$'
CtrF db 10,13,'$'
begin:cld ;正向
Call GetUserInput ;输入子程序
;则对它乘3再加1,如果它是偶数,则对它除以2,如此循环,最终都能够得到1。
.386
cmp EAX,0
jz QuitX
mov CurrentValue,EAX
lea dx,CtrF
mov ah,9
int 21h
next:mov eax,CurrentValue
xor edx,edx
call print_dec
cmp eax,1
jz quit
push eax
mov al,26 ;->
int 29h
pop eax
test eax,1
jz next3 ;偶数
;奇数
next2:add CurrentValue,eax
add CurrentValue,eax
inc CurrentValue
mov eax,CurrentValue
cmp eax,MaxValue
jbe next4
mov MaxValue,eax
jmp short next4
next3: ;偶数
shr eax,1 ;/2
mov CurrentValue,eax
next4:inc Step
jmp short next
quit:lea dx,Dispstr1
call DispProc
mov eax,MaxValue
xor edx,edx
call print_dec
lea dx,Dispstr2
call DispProc
mov eax,Step
xor edx,edx
call print_dec
lea dx,Dispstr3
call DispProc
mov ah,7 ;暂停
int 21h
quitx:mov ah,4ch ;离开
int 21h
;--------------------------------------------------------------------------
;output EDX:EAX 输出64bit子程序 (0-18446744073709551615)
print_dec:pushad
xor ecx,ecx
xchg ebp,edx
mov esi,10 ;div by 10
mov ebx,30h
print_dec1:or ebp,ebp
jz print_dec3
xchg ebp,eax
xor edx,edx
div esi
xchg ebp,eax
div esi
or dl,bl
push dx
inc ecx
jmp short print_dec1
print_dec3:xor edx,edx
div esi
or dl,bl
push dx
inc ecx
or eax,eax
jnz print_dec3
print_dec4:pop ax
int 29h
loop print_dec4
popad
ret
;--------------------------------------------------------------------------
;转值子程序,把输入的10进制文字转成16进制
;输入:ds:si数字字符串起点,以0dh结束
;输出:eax=转换后的16进制值(32bit),cf=1表示有非数字字符
GetValue:push ebx
push edi
xor ebx,ebx
mov edi,10
GetV10:lodsb ;指向起点
and eax,000000ffh ;清除高bit,保留AL
cmp al,0dh ;回车?
;cmp al,0 ;-----zero
jz Getvx
sub al,'0'
cmp al,9
ja Getvy
xchg ebx,eax ;交换
mul edi
add ebx,eax ;累加
jmp short GetV10
Getvx:mov eax,ebx ;ascii转值后由eax转回
clc ;成功cf=0
jmp short Getvz
Getvy:stc ;错误 cf=1
Getvz:pop edi
pop ebx
ret
;-------------------------------------------------------------------
GetUserInput: mov ah,9
lea dx,DispStr ;提示
int 21h
lea dx,InputBuffer ;指向输出缓冲
mov ax,0c0ah ;输入函数,先清空键盘缓冲
int 21h
lea si,InputBuffer + 2
mov cx,0
mov cl,[si-1] ;取实际输入数
jcxz GetUx ;无输入
Call GetValue ;取值子程序,ax传回该值,cf=1表示错误,可能输入非数字
jc GetUserInput ;输入错误,非数字
cmp eax,NLimit ;999999999 ?
ja GetUserInput
ret
GetUx:xor eax,eax
ret
;-------------------------------------------------------------------
DispProc:mov ah,9
int 21h
ret
;-------------------------------------------------------------------
CODE ENDS
END START
[此贴子已经被作者于2016-6-30 13:06编辑过]
程序代码:redate: ;本函数返回某年某月份天数,结果在ax中,调用bx:年,al:月
push bx
push cx
push dx
push ax
mov ah,2ah
int 21h
pop ax
push cx
push dx ;保存当前日期
mov ah,2bh
mov cx,bx
mov dh,al
mov dl,32
ymdlp1: dec dl
int 21h
or al,al
jnz ymdlp1
mov bl,dl
pop dx
pop cx
int 21h ;恢复当前日期
xor ax,ax
mov al,bl
pop dx
pop cx
pop bx
ret
