# برنامه نویسی سطح پایین > برنامه نویسی اسمبلی خانواده x86 >  تقسیم اسمبلی

## vorya1

بابا دمتون گرم میون این همه برنامه نویس کسی نیست تو حل این مسله کمک کنه 
چجوری میشه یه عدد  6 بایتی رو بر 2 بایتی تقسیم کرد

----------


## amin joon

آقا دیگه بهم برخورد....

برای تقسیم به کمک دستور div  حالت های زیر وجود دارد.

1- اگر  m از نوع byte باشد
دستور div m 
متغیر ax را بر m تقسیم میکند.....al=خارج قسمت.....ah=باقیمانده
2- اگر m از نوع word باشد
دستور div m 
متغیر dx:ax را بر m تقسیم میکند....ax=خارج قسمت.....dx=باقیمانده
2- اگر m از نوع dword باشد
دستور div m 
متغیر edx:eax را بر m تقسیم میکند....eax=خارج قسمت.....edx=باقیمانده

----------


## programmerzahra

سلام دوستان 

می خواهم یک برنامه برای تقسیم double word بر  double word  :گریه:  به زبان اسمبلی بنویسم ، ممنون میشم اگه راهنماییم کنید

----------


## Delphi Coder

از رجیسترهای 32 بیتی استفاده کن.

----------


## hashashas

a dd 65987
b dq 458796
reminder dd ?
quotient dd  ?
mov edx, dword ptr b+4
mov eax,dword ptr b
div a
mov reminder,edx
mov quotient,eax

اگه خواستي چهار بايت بر چهار بايت تقسيم كني اول مقسوم چهار بايتي رو به هشت بايت تبديل كن.

----------


## zshaeri

میخواستم بدونم چه جوری 64 بیت را تقسیم بر 32 بیت کنم؟

----------


## badguy

سلام
آقا من یه مشکل دارم :گریه:  من  2 تا عدد 4*16 بیتی (هر کدوم 4 تا word) دارم  میخوام این دوتا رو به هم تقسیم کنم, اصلا نمیدونم چطوری باید تقسیم کنم؟؟ 
استاد هم گیر داده که برا 8086 باید برنامه بنویسید که max ریجستری که ساپرت میکنه 16 بیت هستش! :ناراحت: 
کلی گشتم چیزی پیدا نکردم!!1 :گریه: 
کسی میدونه چطوری باید تقسیم کرد؟؟؟ :متفکر:  :اشتباه:

----------


## xman_1365_x

> میخواستم بدونم چه جوری 64 بیت را تقسیم بر 32 بیت کنم؟


64 bit که آسونه هیچی
32 بیت به این روش

num1_l dd  ?
num1_h dd ?
num2 dd ?
mov eax,num1_l
mov edx,num1_h
div num2


و 16 با روشی که پایینتر توضیح دادم مگر اینکه مقسوم الیه 16 میبود که روش دیگه بشه انجام داد




> سلام
> آقا من یه مشکل دارم من  2 تا عدد 4*16 بیتی (هر کدوم 4 تا word) دارم  میخوام این دوتا رو به هم تقسیم کنم, اصلا نمیدونم چطوری باید تقسیم کنم؟؟ 
> استاد هم گیر داده که برا 8086 باید برنامه بنویسید که max ریجستری که ساپرت میکنه 16 بیت هستش!
> کلی گشتم چیزی پیدا نکردم!!1
> کسی میدونه چطوری باید تقسیم کرد؟؟؟


 باید یاد دبستان بیوفتیم که چطور روی کاغذ تقسیم میکردیم،البته چون اینجا مقسوم الیه بزرگتر از ثبات ما هست راهی که به ذهنم اومد تفریق با حلقه و شمارش کردنه که اون میشه خارج قسمت و کم کردن میشه باقیمانده
همین حالت بلعکس میشه ضرب یعنی با جمع ؛ جمع و تفریقم که کاری نداره فقط باید حواستون به کری و بارو باشه این روش ساده بود و میشه بستش داد برای n bit

----------


## badguy

> و 16 با روشی که پایینتر توضیح دادم مگر اینکه مقسوم الیه 16 میبود که روش دیگه بشه انجام داد
> 
> 
> 
>  باید یاد دبستان بیوفتیم که چطور روی کاغذ تقسیم میکردیم،البته چون اینجا مقسوم الیه بزرگتر از ثبات ما هست راهی که به ذهنم اومد تفریق با حلقه و شمارش کردنه که اون میشه خارج قسمت و کم کردن میشه باقیمانده
> همین حالت بلعکس میشه ضرب یعنی با جمع ؛ جمع و تفریقم که کاری نداره فقط باید حواستون به کری و بارو باشه این روش ساده بود و میشه بستش داد برای n bit



سلام, بچه ها این الگوریتم ایرادش چیه؟؟ من تفریق های متوالی برا تقسیم دو عدد 64 بیتی استقاده کردم, در ظاهر به نظرم الگوریتم درسته ولی نتیجه درست نمیده!!! [ به عکس نگا کنین ]Untitled.png


SALL.
INCLUDE FUNC.INC

DATASG SEGMENT 'DATA'
	V1R4 DW 0
	V1R3 DW 0
	V1R2 DW 1
	V1R1 DW 2354H

	V2R4 DW 0
	V2R3 DW 0
	V2R2 DW 0
	V2R1 DW 3      

	d1 dW 0
	D2 DW 0
	D3 DW 0
	D4 DW 0 


	COUNTER1 DW 0
	COUNTER2 DW 0
DATASG ENDS

STACK SEGMENT 'STACK'
	DW 200H DUP(0)
STACK ENDS

CODE SEGMENT 'CODE'
	ASSUME DS:DATASG,CS:CODE,SS:STACK

MAIN PROC FAR
	MOV AX,DATASG
	MOV DS,AX

		;MAGADIRE AVALIYE RO CHAP MIKONE
	
		CLR 07H
		CURSOR 0,0
		PRINTHEX V1R4,0
		PRINTHEX V1R3,0
		PRINTHEX V1R2,0
		PRINTHEX V1R1,0
		PRINTCHAR '/'
		PRINTHEX V1R4,0
		PRINTHEX V2R3,0
		PRINTHEX V2R2,0
		PRINTHEX V2R1,0

	;T*************EST MIKONE KE MAKHARJ 0 NABASHE******************
	CMP V2R4,0
	JNE .START
	CMP V2R3,0
	JNE .START
	CMP V2R2,0
	JNE .START
	CMP V2R1,0
	JNE .START
	JMP .END
	;*************************************************  ***************

	;SHORO'E TAGSIM
	.START:   
	;*****************TEST MIKONE KE   V1 > V2***********************
	MOV AX,V2R4
	CMP V1R4,AX
	JL .END     
	MOV AX,V2R3
	CMP V1R3,AX
	JL .END     
	MOV AX,V2R2
	CMP V1R2,AX
	JL .END     
	MOV AX,V2R1
	CMP V1R1,AX
	JL .END    
	;*************************************************  **************
	
	;*********************INJA   V1=V1-V2***************************
	   MOV AX,V2R4
	   SUB V1R4,AX

	   MOV AX,V2R3
	   SBB V1R3,AX

	   MOV AX,V2R2
	   SBB V1R2,AX

	   MOV AX,V2R1
	   SBB V1R1,AX

	   ADD COUNTER1,1
	   ADC COUNTER2,0

	   JMP .START
	;****************** INJA TAGSIM TAMOM SHODE *******************
.END:
		;*****************NATAYEJ RO CHAP MIKONE*******************
		PRINTCHAR '='
		PRINTHEX COUNTER2,0
		PRINTHEX COUNTER1,0
		_WAIT
	   MOV AX,4C00H
	   INT 21H
MAIN ENDP
CODE ENDS
	END MAIN

----------


## xman_1365_x

بازم باید به دبستان مراجعه بشه چطور تفریق میکردیم،حلقه شما مشکل داره اول روی کاغذ الگوریتم رو بنویسید بعد پباده سازی کنید
ببنید جواب حاصل شما شده bc6 چون وقتی تفریق میکنید نهایت میشه 
10000/3=bc6
ایراد کارتون واضحه که وقتی اینطور شه باید ازسمت چپ در صورتی که عددی باشه یکی کم شه و به بیت ماقبل اضافه بشه
0ffff/3=5555
و چون شما یک کانتر دارین مجموع دو عدد
5555+bc6=611b
که 611b میشه خروجی شما
موفق باشی

----------


## badguy

> ایراد کارتون واضحه که وقتی اینطور شه باید ازسمت چپ در صورتی که عددی باشه یکی کم شه و به بیت ماقبل اضافه بشه


من تازه واردم , متوجه این تیکه نشدم ! منظورتون از جمله بالا چیه؟؟

مرسی از کمکتون

----------


## xman_1365_x

> من تازه واردم , متوجه این تیکه نشدم ! منظورتون از جمله بالا چیه؟؟
> 
> مرسی از کمکتون


خوب دوست عزیز گفتم که باید تفریق انجام بدین مثال رو در مبنای دسیمال میگم بهتر متوجه شین و پی به اشتباهتون ببرید
میخوایم تقسیم زیر رو انجام بدیم

14/2=؟

شما اینکارو میکنید

14-2=12
count=1
12-2=10
count=2

شما همینجا توقف میکردین و بررسی نمی کردین که باید اعداد بالاترو چک کنید و در صورت امکان یعنی صفر نباشه قرض بگیرید
پس همونطور که دبستان گفتن از عدد با ارزش بیشتر قرض میگیریم برای دسیمال 10 و هگر 16 و اکتال 8 ، باینری 2
سادست فقط چند بار روی کاغذ انجام بدین الگوریتمشو میفهمید حتی بعدش میشه آرایه ای از N رقم و قسمت اعشارم حساب کرد، اما برای محاسبه اونها باید الگوریتم های بهینه استفاده کرد.
در نهایت میشه همینارو با ثباتهای 32 یا 64 بیتی هم انجام داد.

----------


## badguy

مرسی فهمیدم مشکل کجاس.
ولی یه سوال : با این روش شرط اتمام حلقه چیه میشه؟؟ چون یقینا 0 نمییتونه باشه چون ممکنه باقی مانده داشته باشه و همچنین شرط بیشتر مساوی هم نمیتونه باشه چون وقتی عددمون در همون مثال قبلی به این مقدار برسه 0ffff/3 چون 0ffff=-1 هست برا همین از حلقه میزنه میاد بیرون!!!! برا این باید چکار کنیم؟؟ [ مثلا این شزطی بود که من گذاشته بودم و دلیل اینکه 0ffff/3 رو حساب نمیکردم این بود ] 

وقتی با دست حساب میکنیم این مشکل وجود نداره؛ همون طور که گفتم تازه واردم من اینجا چکار کنم که برنامه به 0ffff با چشم یه عدد  unsigned نگا کنه و به صورت unsigned مقایسش کنه؟؟  

            .
            .
            .

            MOV AX,V2R4
            CMP V1R4,AX
                        JAE START1     
            
            MOV AX,V2R3
            CMP V1R3,AX
                        JAE START1  
            
            MOV AX,V2R2
            CMP V1R2,AX
                        JAE START1 
            
            MOV AX,V2R1
            CMP V1R1,AX
                        JL END

            .
            .
            .

----------


## badguy

من اینو تو یکی از کتاب هایه اسمبلی برا CPU های پنتویم برا تقسیم پیدا کردم از همون روش تفریق استفاده کرده ولی کلا نمیدونم داره چکار میکنه؟؟ 
1:                ;-----------------------------------------------------------
2:                ;Divides two 64-bit unsigned numbers A and B (i.e., A/B).
3:                ;The number A is received in EBX:EAX and B in EDX:ECX registers.
4:                ;The 64-bit quotient is returned in EBX:EAX registers and
5:                ;the remainder is retuned in EDX:ECX registers.
6:                ;Divide-by-zero error is indicated by setting
7:                ;the carry flag; carry flag is cleared otherwise.
8:                ;Preserves all registers except EAX, EBX, ECX, and EDX.
9:                ;-----------------------------------------------------------
10:                ; local variables
11:                %define SIGN byte[EBP-1]
12:                %define BIT_COUNT byte[EBP-2]
13:                div64:
14:                               enter 2,0                     ; 2-byte local variable space
15:                               push ESI
16:                               push EDI
17:                               ; check for zero divisor in EDX:ECX
18:                               cmp ECX,0
19:                               jne non_zero
20:                               cmp EDX,0
21:                               jne non_zero
22:                               stc                               ; if zero, set carry flag
23:                               jmp SHORT skip            ; to indicate error and return
24:                               non_zero:
25:                               mov ESI,EDX                 ; ESI:EDI = B
26:                               mov EDI,ECX
27:                               sub EDX,EDX                 ; P = 0
28:                               sub ECX,ECX
29:                               mov SIGN,0
30:                               mov BIT_COUNT,64       ; BIT_COUNT = # of bits
31:                               next_pass:                    ; ****** main loop iterates 64 times ******
32:                               test SIGN,1                    ; if P is positive
33:                               jz P_positive                  ; jump to P_positive
34:                               P_negative:
35:                                                             rcl EAX,1                ; right-shift P and A
36:                                                             rcl EBX,1
37:                                                             rcl ECX,1
38:                                                             rcl EDX,1
39:                                                             rcl SIGN,1
40:                                                             add ECX,EDI            ; P = P + B
41:                                                             adc EDX,ESI
42:                                                             adc SIGN,0
43:                                                             jmp test_sign
44:                               P_positive:
45:                                                             rcl EAX,1                  ; right-shift P and A
46:                                                             rcl EBX,1
47:                                                             rcl ECX,1
48:                                                             rcl EDX,1
49:                                                             rcl SIGN,1
50:                                                             sub ECX,EDI              ; P = P + B
51:                                                             sbb EDX,ESI
52:                                                             sbb SIGN,0
53:                               test_sign:
54:                                                             test SIGN,1                ; if P is negative
55:                                                             jnz bit0                      ; set lower bit of A to 0
56:                               bit1:                                                        ; else, set it to 1
57:                                                             or AL,1
58:                                                             jmp one_pass_done    ; set lower bit of A to 0
59:                               bit0:
60:                                                             and AL,0FEH                ; set lower bit of A to 1
61:                                                             jmp one_pass_done
62:                              one_pass_done:
63:                                                             dec BIT_COUNT           ; iterate for 32 times
64:                                                             jnz next_pass
65:                               div_done:                                                  ; division completed
66:                                                             test SIGN,1                  ; if P is positive
67:                                                             jz div_wrap_up            ; we are done
68:                                                             add ECX,EDI                ; otherwise, P = P + B
69:                                                             adc EDX,ESI
70:                               div_wrap_up:
71:                                                             clc                               ; clear carry to indicate no error
72:                               skip:
73:                                                             pop EDI                        ; restore registers
74:                               pop ESI
75:                               leave                                                         ; clears local variable space
76:                               ret

لطفا کمک کنید, کلا پروژم فقط معطل یه تقسیم لعنتی هستم!!! 3 روز بعد باید پروژم رو تحویل بدم :گریه:

----------


## xman_1365_x

> مرسی فهمیدم مشکل کجاس.
> ولی یه سوال : با این روش شرط اتمام حلقه چیه میشه؟؟ چون یقینا 0 نمییتونه باشه چون ممکنه باقی مانده داشته باشه و همچنین شرط بیشتر مساوی هم نمیتونه باشه چون وقتی عددمون در همون مثال قبلی به این مقدار برسه 0ffff/3 چون 0ffff=-1 هست برا همین از حلقه میزنه میاد بیرون!!!! برا این باید چکار کنیم؟؟ [ مثلا این شزطی بود که من گذاشته بودم و دلیل اینکه 0ffff/3 رو حساب نمیکردم این بود ] 
> 
> وقتی با دست حساب میکنیم این مشکل وجود نداره؛ همون طور که گفتم تازه واردم من اینجا چکار کنم که برنامه به 0ffff با چشم یه عدد  unsigned نگا کنه و به صورت unsigned مقایسش کنه؟؟  
> 
> .
>             .
> 
>             MOV AX,V2R4
> ...


 خوب مثال من و شما در نهایت صفر میشه چرا میگین نمیشه ؟(مجموع ارقامتون بر 3 بخشپذیره) اما اعدادی که صفر نمیشه چرا نمیشه ؟  :لبخند گشاده!:   چون بخشپذیر نیست و باقیمانده میاره،آیا باقیمانده بزرگتر از مقسوم الیه  هست؟ البته باید تا زمانی انجام بشه که سمت چپ عددی نباشه اینم جواب :لبخند:  معلومه که روی کاغذ انجام نمیدین تا من نیام آموزش تفریق بدم
در مورد شرط هاتون از ذهنتون خارج کنید و از نوع فکر کنید برای UNSIGNED هم از دستورات شرطی مربوطه استفاده کنید

JB =JNAE=JC 
JNB=JAE=JNC
JBE=JNA
JNBE=JA

به هر حال دیدین که استادتون چه سوالی بهتون داد که در نگاه اول گفتین  نشدنیه،خودتون سعی کنید چون به اندازه کافی راهنمایی  کردم باید بنویسید و به خطا بخورید و دیباگ کنید برای دیباگ کردن پیشنهاد  میکنم از EMU8086 استفاده کنید که مقدار ثباتها و حافظه و فلگ هارو ببنید  کمکتون میکنه زودتر حلش کنی
موفق باشی

----------


## mhdi_karimi1

سلام دوستان 

کسی میتونه در مورد این سوال منو کمک کنه؟؟؟

یک عدد یک بایتی رو بر عدد یک وردی تقسیم کنین و تا ۴ رقم اعشار انجام بدین

ممنون میشم

----------

