将输入的偶数转换成哥德巴赫猜想,输出哥德巴赫猜想
程序运行:
代码:
datas segmentmaxESLen db 0ffhevenSLen db 0evenString db 0ffh dup(?)evenNumber dw ?prime1 dw 0 prime2 dw 0 inputPrompt db 'input a even number(number>5):$'outputInvail db 0dh,0ah,'Invail$'outputNotEven db 0dh,0ah,'Must be even$'outputNotGreater5 db 0dh,0ah,'Must greater than or equal to 6$'GoldbachConjectureValue db 0dh,0ah, 40 dup(?)datas endsstacks segment stackdb 100h dup(?)stacks endscodes segmentassume cs:codes,ds:datas,ss:stacks
main proc far
start:push dsmov ax,0hpush axmov ax,datas ;初始化dsmov ds,ax;输出输入数字提示lea dx,inputPromptmov ah,9int 21h;输入数字字符串lea dx,maxESLenmov ah,10int 21h;将字符串转换成十进制数lea si,evenStringcall todigit;判断转换是否有效cmp bx,0jnz availableData ;若有效,则跳转;若无效,则输出Invaillea dx,outputInvail mov ah,9int 21hjmp exit ;跳转至退出availableData:mov evenNumber,ax ;保存输入的数cmp ax,6 ;比较该数与6jae s ;若大于等于6,则跳转至判断该数是否是偶数;若小于6,则输出Must greater than or equal to 6lea dx,outputNotGreater5 mov ah,9int 21hjmp exit ;跳转至退出s:test ax,1 ;判断该数是否是偶数jz s1 ;若是偶数,则跳转查找歌德巴赫猜想;若不是偶数,则输出Must be evenlea dx,outputNotEven mov ah,9int 21hjmp exit ;跳转至退出s1:mov ax,evenNumber ;将输入的数移至axcall findGoldbachConjecture ;查找哥德巴赫猜想exit: retmain endptodigit proc near;si=EA ax=number,bx=available;保存寄存器push cxpush dxpush simov ax,0 ;十进制数的低16位mov dx,0 ;十进制数的高16位mov di,10 ;除数mov cl,[si-1] ;将字符串的个数移至clmov ch,0 ;清除chdigits:mov bl,[si] ;将字符移至blcmp bl,'0' ;判断字符与‘0’的大小jl invail ;若小于‘0’,则字符为无效cmp bl,'9' ;判断字符与‘9’的大小jg invail ;若大‘9’,则字符为无效mov bh,0 ;bh清0sub bl,30h ;字符转换成数字的值mul di ;左移一位数乘10add ax,bx ;加上个位的和adc dx,0add si,1 ;移至下一个字符的索引loop digitscmp dx,0 ;比较十进制数的高16位是否为0jnz invail ;若不为0,则跳转说明字符串数是无效的mov bx,1 ;否则设置bx为1jmp dexit ;跳转至退出invail:mov bx,0 ;无效则设置bx为0;恢复寄存器dexit:pop sipop dxpop cxret
todigit endpfindGoldbachConjecture proc near ;ax=source ;保存寄存器push cxpush dxpush bxpush sipush dimov cx,ax ;将哥德巴赫猜想的数移至cxmov si,2 ;从2开始查找素数mov di,cx ;将哥德巴赫猜想的数移至dishr di,1 ;取该数的一半ps:call isPrimeNumber ;判断si是否为素数cmp bx,0 ;判断返回值是否有效jz next ;若不为素数,则跳转下一个数mov dx,cx ;若为素数,则将哥德巴赫猜想的数移至dxsub dx,si ;求差push si ;保存simov si,dx ; 将差移至sicall isPrimeNumber ;判断差是否为素数pop si ;恢复sicmp bx,0 ;判断返回值是否有效jz next ;若不为素数,则跳转下一个数call outputGoldbachConjecture ;若为素数,则输出哥德巴赫猜想next:inc si ;查找下一个数是不是素数cmp si,di ;判断si是否大于哥德巴赫猜想的数的一半jbe ps ;若小于等于,则循环继续;恢复寄存器pop dipop sipop bxpop dxpop cxretfindGoldbachConjecture endpoutputGoldbachConjecture proc near;保存寄存器push axpush di;设置输出哥德巴赫猜想lea di,GoldbachConjectureValue+2 ;设置输出哥德巴赫猜想的数的字符串地址mov ax,evenNumber ;将哥德巴赫猜想的数移至axcall toDecimalist ;转换成数字字符mov byte ptr [di],'=' ;保存‘=’inc di ;移至下一个字符保存的索引mov ax,si ;将第一个素数移至axcall toDecimalist ; 转换成数字字符mov byte ptr [di],'+' ;保存‘+’inc di ;移至下一个字符保存的索引mov ax,dx ;将第二个素数移至axcall toDecimalist ;转换成数字字符mov byte ptr [di],'$' ;设置字符串的结束符;输出哥德巴赫猜想lea dx,GoldbachConjectureValuemov ah,9int 21h;恢复寄存器pop dipop axret
outputGoldbachConjecture endpisPrimeNumber proc near;si=source bx=isPrime;保存寄存器push dxpush sipush dimov bx,si ;将判断素数的数移至bxcmp bx,2 ;判断该数是否为2jz prime ;若为2,则跳转说明该数为素数cmp bx,3 ;判断该数是否为3jz prime ;若为3,则跳转说明该数为素数mov di,bx ;将该数移至dishr di,1 ;取该数的一半mov si,2 ;判断素数从2开始cmp si,di ;判断si是否大于该数的一半ja notPrime ;若大于,则该数不是素数pIS:mov ax,bx ;将该数移至axmov dx,0 ;无符号数扩展 div si ;除以sicmp dx,0 ;判断余数是否为0jz notPrime ;若余数为0,则不是素数,跳转inc si ;若余数不为0,则si加1cmp si,di ;比较si与该数的一半的大小jbe pIS ;若小于等于,继续循环prime:mov bx,1 ;是素数,设置bx为1jmp pexit ;跳转至退出notPrime: mov bx,0 ;不是素数,设置bx为0;恢复寄存器pexit:pop dipop sipop dxret
isPrimeNumber endptoDecimalist proc near;ax=source di=EA;保存寄存器push cxpush dxpush bxmov cx,0 ;计数器,计算十进制数的位数mov bx,10 ;除数ps:mov dx,0 ;无符号数扩展div bx ;除以10push dx ;保存余数inc cx ;计数器加1,位数增加cmp ax,0 ;判断被除数是否为0jnz ps ;若非0,则循环继续ps1:pop dx ;弹出余数add dl,30h ;转换成数字字符mov [di],dl ;保存数字字符;mov ah,2 ;int 21hinc di ;移至下一个字符保存的索引loop ps1 ;恢复寄存器pop bxpop dxpop cxret
toDecimalist endpcodes endsend main