回复 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