当前位置: 代码迷 >> 汇编语言 >> 80X86求给定整数的所有素因子解决办法
  详细解决方案

80X86求给定整数的所有素因子解决办法

热度:5254   发布时间:2013-02-26 00:00:00.0
80X86求给定整数的所有素因子
要求,输入一个整数,求出其所有素因子,并表现为乘积方式,求因子的算法用子程序来实现,例如:输入480,输出,480=2*2*2*2*2*3*5,一定给分求大神给出程序,一定用80X86啊!!谢谢

------解决方案--------------------------------------------------------
好久没有写Windows 32位汇编程序了,这次又写了一个完整的,下面是源代码
Assembly code
;要求,输入一个整数,求出其所有素因子,并表现为乘积方式,求因子的算法用子程序来实现;例如:输入480,输出,480=2*2*2*2*2*3*5。; 如何编译链接该程序; 本程序需使用masm32来编译,若你的masm32安装在c盘,请设置如下环境变量; set include=c:\masm32\include; set lib=c:\masm32\lib; set PATH=c:\masm32\bin;%PATH%; 若本程序名为test.asm,则运行如下命令编译和链接和运行;ml /c /coff test.asm; link /subsystem:console test.obj; test.exe.386.model flat,stdcall ; 32 bit memory modeloption casemap :none  ; case sensitiveinclude windows.incinclude user32.incincludelib user32.libinclude kernel32.incincludelib kernel32.lib.data        inBuffer      db    256 dup(?)  ;输入缓冲区        outBuffer     db    256 dup(?)  ;输出缓冲区        number    dd    ?               ;被分解的数        sqrtNum   dd    ?               ;被分解的数的平方        dwLen     dd    ?               ;字符串长度        tLen      dd    ?               ;        hInput    dd    ?               ;标准输入设备句柄        hOutput   dd    ?               ;标准输入设备句柄                facTab    dd  32 dup(?)         ;number的所有素因子        facCount  dd  ?                 ;number的所有素因子的个数        currFac   dd  ?                 ;number的当前因子.const       szFmtInOut db    '%d',0       szFmtOut1  db    'Please input a number n(0<=n<=000000000)',13,10       szFmtOut2  db    '%d=',0       szFmtOut4  db    '*%d',0       .codemain proc farstart:    invoke GetStdHandle,STD_OUTPUT_HANDLE   ; 获取控制台输出设备的句柄    mov    hOutput,eax    invoke WriteConsole,hOutput,addr szFmtOut1,sizeof szFmtOut1,addr tLen,0        invoke GetStdHandle,STD_INPUT_HANDLE      ; 获取控制台输入设备的句柄    mov hInput, eax    invoke ReadFile,hInput,addr inBuffer,sizeof inBuffer,ADDR tLen,NULL    lea    esi, inBuffer            call   myAtoi           ;转化字符串为一个数    mov    number, eax      ;将这个数存入number        call   mySqrt           ;求number的平方根,    mov    sqrtNum,eax      ;存入sqrtNum    call   dcomp            ;调用因子分解子程序,分解后的因子个数存入facCount,各个因子存入facTab        call output_fac         ;调用output_fac打印number的分解式    xor eax, eax    invoke ExitProcess,eax  ;退出进程    ret main endpdcomp proc fac    push esi    push edi    push ebxdecompose_fac:    mov  currFac,2          ;用第一个素因子2去试商    xor  ecx,ecx            ;素因子个数    mov  ebx,number         ;需要被分解的数    dcom_loop:    xor edx,edx    mov eax,ebx    cmp ebx,1               ;若需要被分解的数r为1,结束循环    jz  dcom_exit        mov esi, currFac            div esi                 ;需要分解的数r除以currFac,商存入eax,余数存入edx    or  edx,edx             jnz case_02             ;余数不为0,转case_02case_01:                    ;余数为0;case 1, ebx / currFac==0       mov edx, currFac        ;当前素因子存入因子表facTab    mov facTab[ecx*4],edx       inc ecx                 ;素因子数+1        mov ebx, eax            ;更新需分解的数r, r=r/currFac     jmp dcom_loop           ;继续分解r    ;case 2: ebx /currFac !=0case_02:                    ;r % currNum !=0    mov edx,currFac             inc edx    mov currFac,edx         ;当前因子+1    cmp edx,sqrtNum         ;如当前因子大于number的平方根,则退出循环    jle dcom_loop          ;currFac>sqrt(number)    mov facTab[ecx*4],ebx   ;将带分解的数r存储素因子表    inc ecx                 ;素因子数+1    dcom_exit:    mov  facCount,ecx       ;素因子数存入facCount        pop ebx    pop edi    pop esi    retdcomp endp    ; esi : in parameter, the address of string; eax : out parameter,the value of string; convert from a string to a integermyAtoi proc fac    push ebx    push ecx        xor eax,eax    xor ecx,ecx    mov ebx,10loop_read_char:      mov    cl,byte ptr [esi] ; get a char from in_buff      sub    cl,'0'      cmp    cl,9      ja     input_exit    ;if the char <'0' or >'9', then jump out loop         mul    ebx      add    eax,ecx        inc    esi      jmp    loop_read_char  input_exit:    pop    ecx    pop    ebx    ret myAtoi endp; number: in parameter; facTab: in paramter; facCount: factor count; hInstance: input device handleoutput_fac proc far    push esi        ;保存寄存器    push edi    push ebx    lea    edi, outBuffer    invoke wsprintf, edi, addr szFmtOut2,number    add    edi, eax        xor    ebx,ebxconvert_loop:       mov   eax,facTab[ebx*4]         or    ebx,ebx    jnz   case2case1:      ;第一个因子,直接输出“因子“到outBuffer    invoke wsprintf, edi,addr szFmtInOut,eax    add   edi, eax  ;edi the write pointer in next time ; 下次输出时的地址送如edi    jmp   next_cmpcase2:      ;非第一个因子,输出“×因子“到outBuffer    invoke wsprintf,edi,addr szFmtOut4,eax    add   edi, eax  ;edi the write pointer in next ; 下次输出时的地址送edi    next_cmp:    inc   ebx    cmp   ebx, facCount    jb    convert_loopprint:      lea   esi, outBuffer    sub   edi, esi    mov   dwLen,edi         ;计算输出的字符串的长度,存入dwLen    invoke WriteConsole,hOutput,addr outBuffer,dwLen,addr tLen,0    ;在控制台输出        pop    ebx              ;恢复寄存器    pop    edi    pop    esi    ret output_fac endp; eax : in parameter,   a 32 bit integer; eax : out parameter,  return sqrt(a), mySqrt proc fac    push ecx        ;保存寄存器    push ebx        mov ecx,eax    mov ebx,1       ;平方根的初始值为1    loop_mysqrt:      mov eax,ebx     ;计算ebx * ebx,结果存入eax    mov edx,ebx    mul edx    cmp eax,ecx     ;ebx的平方大于被开方数?        ja  mysqrt_exit ;若平方根的平方大于被开方数,推出循环    inc ebx         ;平方根+1    jmp loop_mysqrt     mysqrt_exit:    dec ebx         ;因为ebx的平方大于被开方数,故此减1    mov eax,ebx        pop ebx         ;恢复寄存器    pop ecx    ret mySqrt endpend main
  相关解决方案