如和用汇编语言写大数n阶乘

kangkanggggg 2007-07-03 05:36:39
谢谢有谁能给我源代码阿,我急,学校作业没法交了要
...全文
1590 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
liangbch 2007-07-25
  • 打赏
  • 举报
回复
下面这个程序可计算到34049的阶乘,编译为dos下格式的com文件仅仅为254byte(我还有一个161byte的,暂不发表),运行时,输入一个 1-34049的数,运行结果写入到当前目录下的一个txt 文件。

编译方法:
1。将“-----------------------”后的内存另存为fac.asm
2. ml /AT /c fac.asm
3. tlink fac.obj
4. exe2bin fac.exe fac.com

其中:第一个工具ml 来自于masm v6/v7/v8,第二个工具tlink 来自 tc2.0.

-----------------------
.MODEL TINY

MAX_N equ 34049
STACK_LEN equ 32

_TEXT segment ;byte public 'CODE'
org 100h
_main proc near

@00: jmp @100

@43:
;out loop header
mov si,6
xor cx,cx
;
cmp [si],cx
jnz @44

;
push si
lodsw
;
@43_5:
lodsw ;[si]-->ax
mov [si-4],ax
cmp si,bp
jbe @43_5
;
pop si
add word ptr [si-2],4 ;[0004]+=4
dec bp
dec bp

;cx still is 0
;si still point to 6
@44:
;inner loop header
mov word ptr ax,[si]
mul bx ; *= i
add ax,cx ; +=carry
adc dx,0
@45:
div di ;save current digital
mov word ptr [si],dx ;save current digtial to buff
inc si
inc si
mov cx,ax ;move carry to cx
xor dx,dx
cmp si,bp
jbe @44
or ax,ax
jnz @45

@46:
lea bp,[si-2] ;calc end address of buff


@46_5:
dec bx ;i--
jnz @43

;calulation is completed
;convert number to string
@47:
;init
std
pop bx ;restore file handle to bx
mov si,bp ;si, the end address of buff, si will decrease
dec bp
dec bp ;di: it always point to address of buff-2

@48: ;out loop header
lodsw ;move [si] to ax
mov cl,4
mov di,3 ;overwrite code
@49:
;inner loop header ;convert a word to 4 digital sign
xor dx,dx ;covert a word to 4 dec digital
push di
mov di,10
div di
pop di
add dl,'0'
mov byte ptr [di],dl
dec di
loop @49
@50:
mov cl,5

@51: ;do while loop,at least be excuted one times
inc di
dec cx

cmp si,bp
jnz @52

cmp byte ptr [di],'0'
jz @51

@52:
mov dx,di
;bx: ,file handle
mov ah,40h ;Write file dos call
int 21h


cmp si,6
jae @48

@53:
mov cx,word ptr [si] ;mov [0004] to cx
or cx,cx
jz @54

xor di,di
cld
mov al,'0' ;di is end address of buff
push cx
rep stosb
pop cx

xor dx,dx
mov ah,40h
int 21h
@54: ;

; close files
;Function (ah): 3Eh
;Entry parameters: bx- File Handle
;Exit parameters: If the carry flag is set, ax contains 6, the only possible error, which is an invalid handle error

mov ah, 3eh ;close file dos call
int 21h
@60:
int 20h

@100:
; printf prompt string
mov si,offset DGROUP:_buff+2
lea dx,[si-2]
mov ah,09h
int 21h

;input a string from console
mov ah,0ah
int 21h

xor ax,ax ;ax return value
mov bp,10
push si ;save address of buff+2
@101:
mov cl,byte ptr [si]
sub cl,'0'
cmp cl,9
ja @120

cmp ax,MAX_N/10
ja @60
@110:

mul bp
add ax,cx; register ch should be zero

inc si
mov di,si
jmp @101
@120:
or ax,ax
jz @60 ;invalid value, teminal program
@130:
pop dx ;the address number string
push ax ;save value of n to stack
;di: end of number string and shift 1
mov si,offset DGROUP:_fileName
mov cl,6 ;cx is file length ,ch always equ to 0
rep movsb ;dx is end address of number string

; create a file
; dx: fileName
; cx should be zero
mov ah, 3ch ; create a file
int 21h ; ax:file handle
pop bx ; restore value of n from stack

jc @60

;
push ax ;ax: _fp
;
mov ax,ds
add ax,1000h
push ax
pop ds
push ax
pop es
;
mov di, 6 ;di: start address of buff, it should align 2 byte
mov bp, di
mov word ptr [di-2],cx ;[0004]=0
inc cx
mov word ptr [di],cx ;[0006]=1;
mov di,10000

jmp @43

_main endp


_buff label byte
db 'n'
db '='
db '?'
db '('
db '0'
db '<'
db 'n'
db '<'
db '3'
db '4'
db '0'
db '5'
db '0'
db ')'
db '$'

_fileName label byte
db 33
db 46
db 116
db 120
db 116
db 0
_TEXT ends

public _fileName
public _main


end _main
liangbch 2007-07-25
  • 打赏
  • 举报
回复
to foxdeng(江洋大刀) :深有同感,经常在 csdn 汇编板块 和 programfan 汇编板块看到有汇编实现这个,那个的帖子。
我以为,要用 合适的工具作合适的工作,并非合适问题都有用汇编去做,用汇编写程序的理由有以下几种:
1。高级语言实现不了或者实现起来很困难,如程序加密,病毒等。
2。因为性能上的原因,使用汇编语言提速,看看GMP的源代码会发现大量的汇编代码。使用汇编语言还可能享用一些高级指令的好处,如在计算整数的log2 时,使用bsr指令。还有,使用SSE,SSE2 来提速等。
3。出于一些其他目标,如追求目标程序尽可能小等。

切记:用合适的工具作合适的工作,钢锯条可以据大树,但几乎没有人这么做,除非你不考虑效率。

mengshijie_1981 2007-07-25
  • 打赏
  • 举报
回复
最原始的思想往往是行之有效的,是最朴素的思想,解决起问题来也是最自然最容易理解的。
假设求100!
1.
(0).首先开辟一块内层,用于存放结果,初始化结果=100
(1).用CX作为最外层的计数器
(2).内层采用 结果=结果*(CX-1),循环99次就完成了任务
2.
编写一个函数,实现任意大小的两个数的乘法,可以用参数控制被乘数和乘数的位数,也可以采用固定值,比如50位16进制乘法,相信100!这个结果绝不会超过100位16进制的表示范围。
函数的实现方法采用:移位和相加的办法实现。
这里面又会出现一个函数,或者使用循环嵌套的方法实现。不过我还是偏向于使用函数实现,即便增加了过程调用的深度,但是能够利用模块化调试的优点。
paulbin 2007-07-23
  • 打赏
  • 举报
回复
我顶楼上的

我参加工作第一个老板强制要求写汇编,我感觉那效率太低了方式太落后了,最后我被开了,哈哈
foxdeng 2007-07-21
  • 打赏
  • 举报
回复
其实不算难,我通常的做法是,用c写成这种功能的代码,再用-s的方式变成汇编,你再手工修改就行了。
其实真正用到汇编的场合是不多的。以本人所为例,我是为嵌入式设备写底层驱动。以一般人的 看来可能要写很多的汇编了吧,其实我只在曾在移植os的时候写过几个用于引导的汇编文件,其余的全部是用c的。最多的,在调试c时会顺便看看运行时的汇编代码是什么情况。

我个人觉得,汇编有如冷兵器时代的匕首,你可以将它玩得出神入化,但是你现在还能单单指望这个东西在战场上克敌制胜吗?
请用汇编实现xx,这是我经常在这个板块上看到的标题,其实这些复杂的东西用c来实现才是正道,汇编的用处只有用在那些需要极力优化的,引导系统的必须部件,还有就是反向工程。
学汇编的重点应该是,在理解汇编指令基础上再花大力气吃透汇编与c的混合原理;吃透c编译成汇编会是什么样子;在不知道或者只知道部分源代码的情况下破解一些关键部分等等。
有一本叫《深入理解计算机系统》的书,在该书里用较大的篇幅提及到这个问题,各位不妨去瞧瞧
meiyululu 2007-07-21
  • 打赏
  • 举报
回复
I have the source ,If you need ,I can give you.
liangbch 2007-07-09
  • 打赏
  • 举报
回复
看看这个:http://topic.csdn.net/t/20050719/13/4154011.html
另外,你可以拿 可执行文件来交差。
zhu3x 2007-07-04
  • 打赏
  • 举报
回复
用数组+循环指令
mengshijie_1981 2007-07-04
  • 打赏
  • 举报
回复
通常的做法都是用数组和调整指令配合完成的,实现起来很麻烦,查阅一些资料吧!
czlyc006 2007-07-04
  • 打赏
  • 举报
回复
我就是当n很大,结果超过寄存器16位,应该怎么做啊,请高手指点指点
------------------------------------------------------------------
mul指令会自动把存放结果的数据位扩展为原先的2倍,即32位,高16位存放在dx中,低16位存放在ax
如果运算结果大于32位的话,参考楼上所言,或者使用32位汇编
kangkanggggg 2007-07-03
  • 打赏
  • 举报
回复
我就是当n很大,结果超过寄存器16位,应该怎么做啊,请高手指点指点
czlyc006 2007-07-03
  • 打赏
  • 举报
回复
作业帖,告诉你思路吧
先写成C++代码,然后照着逻辑改成汇编
*运算符对应mul指令(无符号情况下),for循环(例如for(int i=0;i<=n;i++))中的循环计数器i对应cx或ecx寄存器,整个循环以标号开头,loop结尾
剩下的就是一些程序的惯例格式,把书上程序代码千篇一律的那部分抄上去就行

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧