PDA

نسخه کامل مشاهده نسخه کامل : 2 سوال در مورد الگوریتم تبدیل مبنا در زبان اسمبلی



sia0368
12-03-2009, 09:50
قبلا تبدیل مبنا رو تو پاسکال و c نوشته بودم ولی الان تو اسمبلی به دو تا مشکل برخوردم یکی در مورد تبدیل مبنای غیر دهی به ده مثل باینری به دسیمال که باید اعداد رو یکی یکی در ارزش اون عدد ضرب کرد الان سر به دست آوردن ارزش اعداد برای ضرب کردن گیر کردم یا همون به توان رسوندن
مشکل دیگرم هم سر تقسیمهای متوالیه که باید باقیمانده رو برعکس چاپ کنیم بدون آرایه و با پوش و پاپ چهجوری میشه
یه برنامه از تو اینترنت گیر اوردم که کامله ولی از الگوریتم تبدیل مبناش چیزی سر در نیاوردم در ضمن از دستورات سطح بالا استفاده کرده مثل .if من با همون دستورای معمولی میخوام این کار رو انجام بدم
.model small
.stack 100h
.data
base db 10
base1 db 10
base2 db 10
op db 0
digit db 0
Number dw 0
Number1 dw 0
Number2 dw 0

End_Loop db 0
App_State db 0

str_newLine db 10,13,"$"
str_BlankLine db 80 dup(32),"$"
str_Numbers db "0123456789ABCDEF"

msg_MainMenu db "> Main Menu","$"
msg_MainMenu_1 db " [1] Calculator","$"
msg_MainMenu_2 db " [2] Convert Base","$"
msg_MainMenu_3 db " [3] Exit","$"

msg_Calc_Step_0 db "Base:$"
msg_Calc_Step_1 db "First Number:$"
msg_Calc_Step_2 db "Oprateion:$"
msg_Calc_Step_3 db "Second Number:$"

msg_Cnvrt_Step_1 db "First Base:$"
msg_Cnvrt_Step_2 db "Number:$"
msg_Cnvrt_Step_3 db "Second Base:$"
msg_Cnvrt_Step_4 db "Convertation Result:$"

msg_Base db "Base: $"
err_BadBase db "ERROR: Base most be in 2 to 10 and 16.$"
err_BadOpration db "ERROR: Only + , - , * or /$"

msg_EnterYourChoice db " >Enter Your Choice: ","$"

.code
START:
MOV AX,@data
MOV DS,AX

App_Loop:
MOV App_State,0
CALL MainMenu

.if App_State == 1
CALL Calculate
.endif

.if App_State == 2
CALL BaseConvert
.endif

CMP App_State,-1
JNE App_Loop
App_End:
;exit to dos
MOV AX,4C00h
INT 21h

WriteDX PROC
MOV AH,9
INT 21h
RET
WriteDX ENDP

WriteNumber PROC
PUSH CX
PUSH BX

MOV AX,Number
MOV BH,0
MOV BL,base
XOR CX,CX
WNP_L1:
XOR DX,DX
DIV BX
PUSH DX
INC CX
CMP AX,0
JE WNP_L2
JMP WNP_L1
WNP_L2:
POP BX
MOV Dl,str_Numbers[BX]
MOV AH,2h
INT 21h
LOOP WNP_L2

POP BX
POP CX
RET
WriteNumber ENDP

PutCharDl PROC
MOV AH,2
INT 21h
RET
PutCharDl ENDP

NewLine PROC
MOV AH,9
MOV DX,OFFSET str_newLine
INT 21h
RET
NewLine ENDP

ClearLineDh PROC
MOV DL,0
CALL GotoDhDl
MOV AH,9
MOV DX,OFFSET str_BlankLine
INT 21h
RET
ClearLineDh ENDP

GotoDhDl PROC
MOV AH,02h
MOV BH,0
INT 10h
RET
GotoDhDl ENDP

ReadKey PROC
MOV AH,7
INT 21h
RET
ReadKey ENDP

ReadNumber PROC
MOV Number,0
MOV End_Loop,0
.repeat
CALL ReadKey
MOV CL,-1
.if AL == 13
MOV End_Loop,1
.endif
.if AL >= "0" && AL <= "9"
MOV CL,AL
SUB CL,"0"
.endif
.if AL >= "a" && AL <= "f"
MOV CL,AL
SUB CL,"a"
ADD CL,10
.endif
.if AL >= "A" && AL <= "F"
MOV CL,AL
SUB CL,"A"
ADD CL,10
.endif
.if CL < base
MOV BX,0
MOV BL,CL
MOV DL,str_Numbers[BX]
CALL PutCharDl

XOR DX,DX
MOV AX,Number
MOV BH,0
MOV BL,base
MUL BX
MOV CH,0
ADD AX,CX

MOV Number,AX
.endif
.until End_Loop == 1
RET
ReadNumber ENDP

ClearScreen PROC
MOV AH,06h
MOV AL,0
MOV BH,1Fh
MOV CX,0
MOV DH,24
MOV DL,79
INT 10h
MOV DX,0
CALL GotoDHDL
RET
ClearScreen ENDP

MainMenu PROC
CALL ClearScreen
CALL NewLine
MOV DX,OFFSET msg_MainMenu
CALL WriteDX
Call NewLine
Call NewLine
MOV DX,OFFSET msg_MainMenu_1
CALL WriteDX
Call NewLine
MOV DX,OFFSET msg_MainMenu_2
CALL WriteDX
Call NewLine
MOV DX,OFFSET msg_MainMenu_3
CALL WriteDX
Call NewLine
Call NewLine
MOV DX,OFFSET msg_EnterYourChoice
CALL WriteDX

LBL_MM_1:
CALL ReadKey
CMP AL,"1"
JL LBL_MM_1
CMP AL,"3"
JG LBL_MM_1

.if AL=="1"
MOV App_State,1
.endif
.if AL=="2"
MOV App_State,2
.endif
.if AL=="3"
MOV App_State,-1
.endif

RET
MainMenu ENDP

Calculate PROC
CALL ClearScreen
JMP LBL_C_1
LBL_C_0:
CALL NewLine
MOV DX,OFFSET err_BadBase
CALL WriteDX
CALL NewLine
LBL_C_1:
MOV DX,OFFSET msg_Calc_Step_0
CALL WriteDX
MOV base,10
CALL ReadNumber
MOV AX,Number

CMP AX,2
JL LBL_C_0
.if AX > 10 && AX != 16
JMP LBL_C_0
.endif

MOV base,AL
CALL NewLine

MOV DX,OFFSET msg_Calc_Step_1
CALL WriteDX
CALL ReadNumber
MOV AX,Number
MOV Number1,AX

LBL_C_2:
CALL NewLine
MOV DX,OFFSET msg_Calc_Step_2
CALL WriteDX
CALL ReadKey
MOV DL,AL
CALL PutCharDl
.if AL != "+" && AL != "-" && AL != "*" && AL != "/"
CALL NewLine
MOV DX,OFFSET err_BadOpration
CALL WriteDX
JMP LBL_C_2
.endif
MOV op,AL
CALL NewLine

MOV DX,OFFSET msg_Calc_Step_3
CALL WriteDX
CALL ReadNumber

MOV AX,Number
MOV Number2,AX

CALL NewLine
MOV AX,Number1
MOV Number,AX
CALL WriteNumber
MOV DL,op
CALL PutCharDl
MOV AX,Number2
MOV Number,AX
CALL WriteNumber
MOV DL,"="
CALL PutCharDl

MOV AX,Number1
MOV DX,Number2

.if op == "+"
ADD AX,DX
MOV Number,AX
.endif
.if op == "-"
SUB AX,DX
MOV Number,AX
.endif
.if op == "*"
PUSH DX
PUSH AX

MOV BX,DX
XOR DX,DX
MUL BX

MOV Number,AX
POP AX
POP DX
.endif
.if op == "/"
PUSH DX
PUSH AX

MOV BX,DX
XOR DX,DX
DIV BX

MOV Number,AX
POP AX
POP DX
.endif

CALL WriteNumber
CALL ReadKey

RET
Calculate ENDP

BaseConvert PROC
CALL ClearScreen
JMP LBL_Cnv_1
LBL_Cnv_0:
CALL NewLine
MOV DX,OFFSET err_BadBase
CALL WriteDX
CALL NewLine
LBL_Cnv_1:
MOV DX,OFFSET msg_Cnvrt_Step_1
CALL WriteDX
MOV base,10
CALL ReadNumber
MOV AX,Number

CMP AX,2
JL LBL_Cnv_0
.if AX > 10 && AX != 16
JMP LBL_Cnv_0
.endif

MOV AX,Number
MOV base1,AL

CALL NewLine
MOV DX,OFFSET msg_Cnvrt_Step_2
CALL WriteDX
MOV AL,base1
MOV base,AL
CALL ReadNumber
MOV AX,Number
MOV Number1,AX

JMP LBL_Cnv_3
LBL_Cnv_2:
CALL NewLine
MOV DX,OFFSET err_BadBase
CALL WriteDX
LBL_Cnv_3:
CALL NewLine
MOV DX,OFFSET msg_Cnvrt_Step_3
CALL WriteDX
MOV base,10
CALL ReadNumber
MOV AX,Number

CMP AX,2
JL LBL_Cnv_2
.if AX > 10 && AX != 16
JMP LBL_Cnv_2
.endif

MOV AX,Number
MOV base,AL

CALL NewLine
MOV DX,OFFSET msg_Cnvrt_Step_4
CALL WriteDX
MOV AX,Number1
MOV Number,AX
CALL WriteNumber

CALL ReadKey

RET
BaseConvert ENDP

END START

sia0368
12-03-2009, 16:43
كسي بلد نيست؟يا سوالم رو متوجه نشديد؟يا حال جواب دادن نداريد كدومشه

sia0368
14-03-2009, 17:24
اگه نمیدونید حداقل میتونید بگید با چه الگوریتمی میشه مبنای 2 رو به 10 برد در اسمبلی؟مبنای 10 به مبناهای دیگهرو نوشتم فقط سر این تیکش گیر کردم دقت کنید که تو پاسکال قبلا نوشتم تو اسمبلی گیر کردم

hoax3r
15-03-2009, 15:53
سلام
اینجا قوانین به این صورته که شما باید کدی که نوشتی و به مشکل برخوردی اینجا بزاری تا دیگران بتونن راهنمایی کنند
من تبدیل باینری به دسیمال رو نوشتم داخلش یه توضیحات مختصری هم دادم
اگر با دستورات مشکلی داشتین پیشنهاد میکنم حتما اول به کتابای درسی مراجعه کنید
بعد در صورت مشکل باز اینجا مراجعه کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

شاد باشید

sia0368
16-03-2009, 19:28
سلام
اینجا قوانین به این صورته که شما باید کدی که نوشتی و به مشکل برخوردی اینجا بزاری تا دیگران بتونن راهنمایی کنند
من تبدیل باینری به دسیمال رو نوشتم داخلش یه توضیحات مختصری هم دادم
اگر با دستورات مشکلی داشتین پیشنهاد میکنم حتما اول به کتابای درسی مراجعه کنید
بعد در صورت مشکل باز اینجا مراجعه کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

شاد باشید
در حالتی که معلوم باشد از چه مبنایی به چه مبنایی باید تبدیل شود(برای مثال باینری به دسیمال) و چند رقم کاربر وارد میکند(شما در برنامه ای که گزاشتید 8 بیت رو به صورت پیش فرض گزاشتید) ولی اگر به طور مثال:
برای تبدیل مبنای 3 به 10(دسیمال) ارزش عدد سوم معادل 3 به توان 2 یا به عبارتی 9 میشود و برای مبنای 4 معادل 16 میشود برای این مشکل کسی راه حلی بلده؟
در ضمن من الگوریتمی رو که میخوام بدون دستورات سطح بالا باشه با همون 4 عمل اصلی و کلا دستورات معمول این کارها رو انجام بده
راستی تو این برنامه متوجه نشدم 2 رو به توان cl رسوندید؟(البته هنوز سراغ دفتر کتابم نرفتم.عیده دیگه)

hoax3r
16-03-2009, 23:13
من فکر می کردم فقط برای مبنای 2 به 10 میخواید، اگه فقط مشکل تو همین قسمت ضرب کردنه میتونی اینکارو کنید
توی یک حلقه دونه دونه رقم های عدد مورد نظر رو جدا میکنه یک ثبات در نظر بگیرید مثلا اگه مبنای 3 رو با 10 می خواید ببرید
یه مقدار اولی به اون ثبات بدین بعد در هر بار اجرای حلقه یک بار اون ثبات رو ضرب در مبنا کنید.
من یک برنامه میزارم که قبلا نوشتم، 32 بیتی هست اگه 16 بیتی کار میکنید باید کمی تغییرش بدین، ولی الگوریتمش مشخصه
مبنا و رشته و طول رشته رو هم میتونید تغییر بدین

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


راستی تو این برنامه متوجه نشدم 2 رو به توان cl رسوندید؟

بله


البته هنوز سراغ دفتر کتابم نرفتم.عیده دیگه

عید که برای جبران درسا ما تازه کتابامونو از کمد بیرون میاریم بخونیمشون

sia0368
20-03-2009, 10:55
میبخشید این برنامه رو نوشتم ولی اشکالش نمیدونم کجاست این برنامه در اصل باید مبناهای بین 2 تا 10 رو به هم تبدیل کنه ولی فعلا مبنای n به 10 رو نوشتم(به ترتیب عدد رو تقسیم بر 10 میکنه و باقیمانده رو ضرب در مبنای اولیه میکنه و خارج قسمت رو جای اون عدد میزاره این قدر این کار رو انجام بده تا خارج قسمت صفر شه) که همینش هم ارور میده کسی میتونه راهنماییم کنه ایرادش کجاست تابع enterbyte یه عدد چند رقمی رو تو متغیر n ذخیره میکنه و یکی از گیرهایی که میده سر ریختن کد اسکی 10 به dl هست نفهمیدم مشکلش چیه

model small.
.stack 64
.data
msg_menu_0 db "menu$"
msg_menu_1 db '[1]base converter','$'
msg_menu_2 db '[2]calculator','$'
msg_menu_3 db '[3]exit','$'
msg_menu_4 db '>enter your choice:','$'

msg_base_0 db 'enter source base:','$'
msg_base_1 db 'enter a number to convert:','$'
msg_base_2 db 'enter destination base:','$'
str_newline db 10,13,'$'

;base convert variables
n db ?
number_base db ?
hnumber_base db ?
first_base db ?
hfirst_base db ?
second_base db ?
result db ?
result_base db ?
.code
start: mov ax,@data
mov ds,ax
lea dx,msg_menu_0
call writemsg
call newline
lea dx,msg_menu_1
call writemsg
call newline
lea dx,msg_menu_2
call writemsg
call newline
lea dx,msg_menu_3
call writemsg
call newline
lea dx,msg_menu_4
call writemsg
call newline
a1:
call readkey
cmp al,'1'
je base_convert

base_convert:
call clrscr
lea dx,msg_base_0
call writemsg
r1:
call enterbyte
mov dl,'10' ;;;;;;;;;;;;;;;
mov first_base,n
call newline
lea dx,msg_base_1
call writemsg
mov dl,first_base
call enterbyte
mov number_base,n
lea dx,msg_base_2
call writemsg
mov dl,'10'
call enterbyte
mov second_base,n
cmp first_base,'10'
jne endz
;call dec_to_n
endz:
call n_to_10
;;;;;;;;;;;;;;;;procedures;;;;;;;;;;;;;;;;;;;;
;dec_to_n proc

n_to_10 proc
mov hnumber_base,number_base
mov hfirst_base,first_base
sub hfirst_base,'0'
sub hnumber_base,'0'
c1:
mov ax,hnumber_base
mov bl,10
div bl ;number_base/10 al=kharej ah=baghi
mov dl,al ;al=baghi dar dl rikhte shavad
mov al,ah
mul hnumber_base
add result_base,ax
mov al,2 ;arzeshe adadi har bar 2 barabar mishavad
mul hnumber_base
mov hnumber_base,ax
cmp dl,0
jne c1
mov result,result_base
ret
n_to_10 endp

enterbyte proc ;save a number in n
mov al,0
mov n,al
l1:mov ah,7
int 21h
cmp al,13
je lend
cmp al,'0'
jb l1
cmp al,dl
ja l1
mov dl,al
mov ah,2
int 21h
sub dl,'0'
mov al,n
mov bl,10
mul bl
add al,dl
mov n,al
jmp l1
lend:
call newline
ret
enterbyte endp
;;;;;;;;;;;;;;;;;
Writemsg PROC
MOV AH,9
INT 21h
RET
Writemsg ENDP
;;;;;;;;;;;;;;;;;
NewLine PROC
MOV AH,9
MOV DX,OFFSET str_newLine
INT 21h
RET
NewLine ENDP
;;;;;;;;;;;;;;;;
clrscr PROC
MOV AH,06h
MOV AL,0
MOV BH,1Fh
MOV CX,0
MOV DH,24
MOV DL,79
INT 10h
MOV DX,0
CALL GotoDHDL
RET
clrscr ENDP
;;;;;;;;;;;;;;;
GotoDhDl PROC
MOV AH,02h
MOV BH,0
INT 10h
RET
GotoDhDl ENDP
;;;;;;;;;;;;;
ReadKey PROC
MOV AH,7
INT 21h
RET
ReadKey ENDP