جدول ضرب اسمبلی

aida-joon

New Member
این کد را قبلا تو سایت دیدم
لطفا یه توضیح کوچلو براش بنویسید.
ممنون:rose:
کد:
.MODEL SMALL
.STACK
.DATA
    msg DB 13,10,"Press any key to continue.",13,10,"$"
.CODE
.STARTUP
    MOV     BH, 1
loop_1:
    MOV     BL, 1
loop_2:
    MOV     AL, BL
    MUL     BH
    MOV     AH, AL
    CALL    decimalprint
    MOV     CL, AL
    MOV     AH, 2
    MOV     DL, " "
    INT     21H
    CMP     CL, 100
    JNB     next_1
    INT     21H
next_1:
    CMP     CL, 10
    JNB     next_2
    INT     21H
next_2:
    INC     BL
    CMP     BL, 10
    JBE     loop_2
    MOV     DL, 13
    INT     21H
    MOV     DL, 10
    INT     21H
    INC     BH
    CMP     BH, 10
    JBE     loop_1
    MOV     AH, 9
    LEA     DX, msg
    INT     21H
    MOV     AH, 8
    INT     21H
    .EXIT

decimalprint:
    PUSH    AX
    PUSH    BX
    PUSH    CX
    PUSH    DX
    MOV     CX, 0
    MOV     AL, AH
    MOV     BL, 10
loop_3:
    MOV     AH, 0
    DIV     BL
    PUSH    AX
    INC     CX
    CMP     AL, 0
    JNE     loop_3
    MOV     AH, 2
loop_4:
    POP     DX
    MOV     DL, DH
    ADD     DL, "0"
    INT     21H
    LOOP    loop_4
    POP     DX
    POP     CX
    POP     BX
    POP     AX
    RET
ENd
 
آخرین ویرایش:

the_king

مدیرکل انجمن
این کد را قبلا تو سایت دیدم
لطفا یه توضیح کوچلو براش بنویسید.
ممنون:rose:

تعریف مدل حافظه :
کد:
.MODEL SMALL

تعریف سگمنت پشته :
کد:
.STACK

تعریف سگمنت داده :
کد:
.DATA

تعریف رشنه ای برای پیغام انتهای برنامه :
کد:
    msg DB 13,10,"Press any key to continue.",13,10,"$"

تعریف سگمنت کد :
کد:
.CODE

آماده سازی برای شروع کد :
کد:
.STARTUP

مشخص کردن مقدار اولیه برای شماره سطر، که از 1 شروع شده و تا 10 ادامه می یابد :
کد:
    MOV     BH, 1

حلقه اول برای پیمایش سطر ها از 1 الی 10 :
کد:
loop_1:

مشخص کردن مقدار اولیه برای شماره ستون، که از 1 شروع شده و تا 10 ادامه می یابد :
کد:
    MOV     BL, 1

حلقه دوم برای پیمایش ستون ها از 1 الی 10 :
کد:
loop_2:

چون برای ضرب کردن مقادیر یک عملوند باید در AL/AX باشد، مقدار BL را در AL قرار می دهیم تا در BH ضرب کنیم :
کد:
    MOV     AL, BL

مقدار AL (برابر با BL) در BH ضرب می شود و نتیجه مطابق با ساختار زبان ماشین در AX قرار می گیرد :
کد:
    MUL     BH

مقدار حاصلضرب حداکثر 100 است که در بایت AL جا می گیرد و AH قطعا 0 می ماند، چون decimalprint را طوری
نوشته ایم که مقدار AH را نمایش دهد، مقدار AL را در AH قرار می دهیم :
کد:
    MOV     AH, AL

روتین نمایش مقدار AH را اجرا می کنیم :
کد:
    CALL    decimalprint

بعد از نمایش هر مقدار باید یک یا چند کاراکتر فاصله را نمایش دهیم (تعدادش بستگی به چند رقمی بودن مقدار دارد)،
و برای اینکار به AX در وقفه 21h نیاز داریم، پس قبل از اینکار مقدار فعلی AL را در CL قرار می دهیم تا مقدارش را از
دست ندهیم :
کد:
    MOV     CL, AL

سرویس 2 از وقفه 21h، نمایش کاراکتر موجود در DL روی صفحه نمایش :
کد:
    MOV     AH, 2
    MOV     DL, " "
    INT     21H

در ادامه باید تعداد کاراکتر های فاصله را با طول رقم نمایش داده شده طوری متناسب کنیم که ستون ها
زیر هم قرار بگیرند.
اگر مقدار CL (کپی AL که از ضرب BL در BH بدست آمده بود) از 100 کمتر نبود، پس عدد سه رقمی است :
کد:
    CMP     CL, 100

ولی اگر به چنین وضعیتی نرسیده ایم (اعداد تک یا دو رقمی) به next_1 پرش کن :
کد:
    JNB     next_1

برای اینکه عدد سه رقمی است، یک کاراکتر فاصله دیگر را نیز نمایش می دهیم :
کد:
    INT     21H

در وضعیت جدیدی بررسی می کنیم که عدد تک رقمی است یا خیر.
کد:
next_1:

عدد نسبت به 10 چه وضعیتی دارد؟
کد:
    CMP     CL, 10

اگر عدد از 10 کوچکتر نبود پرش کن :
کد:
    JNB     next_2

وگرنه یک کاراکتر فاصله دیگر را برای تک رقمی بودن عدد نمایش بده :
کد:
    INT     21H

در هر صورت نمایش عدد و فاصله های بعد از آن به پایان رسیده :
کد:
next_2:

شماره ستون را یک واجد افزایش می دهیم :
کد:
    INC     BL

آیا BH به 10 رسیده؟
کد:
    CMP     BL, 10

اگر نرسیده، حلقه loop_2 را ادامه بده :
کد:
    JBE     loop_2

بعد از نمایش هر سطر با نمایش کاراکتر هایی با کد 13 و 10 به سطر بعدی می رویم :
کد:
    MOV     DL, 13
    INT     21H
    MOV     DL, 10
    INT     21H

شماره سطر را افرایش می دهیم :
کد:
    INC     BH

آیا شماره سطر به 10 رسیده؟
کد:
    CMP     BH, 10

اگر نرسیده حلقه loop_1 را تکرار کن :
کد:
    JBE     loop_1

سرویس 9 از وقفه 21h، نمایش رشته اشاره شده توسط DX :
کد:
    MOV     AH, 9
    LEA     DX, msg
    INT     21H

سرویس 8 از وقفه 21h، دریافت یک کلید از صفحه کلید :
کد:
    MOV     AH, 8
    INT     21H

خروج از برنامه :
کد:
    .EXIT

نمایش عدد موجود در AH از طریق تقسیم های متوالی عدد بر 10 و جداکردن باقیمانده تقسیم :
کد:
decimalprint:
    PUSH    AX
    PUSH    BX
    PUSH    CX
    PUSH    DX
    MOV     CX, 0
    MOV     AL, AH
    MOV     BL, 10
loop_3:
    MOV     AH, 0
    DIV     BL
    PUSH    AX
    INC     CX
    CMP     AL, 0
    JNE     loop_3
    MOV     AH, 2
loop_4:
    POP     DX
    MOV     DL, DH
    ADD     DL, "0"
    INT     21H
    LOOP    loop_4
    POP     DX
    POP     CX
    POP     BX
    POP     AX
    RET

پایان فایل :
کد:
ENd
 

the_king

مدیرکل انجمن
سلام
اگه بجای 10*10 ،n*n باشه
باید چیکار کرد:rose:

چون مقادیر سطر و ستون BH و BL در اندازه بایت (8 بیتی) هستند، در بخش DATA. یک متغیر n از نوع بایت (DB)
تعریف کنید که مقدارش رو همون اول برنامه با روتینی مثل get_number از کاربر دریافت کنه :
کد:
.DATA
    msg DB 13,10,"Press any key to continue.",13,10,"$"
    n DB ?

در ادامه هر جای برنامه که عدد 10 برای مقایسه بکار رفته بود، 10 رو به n تغییر دهید :
کد:
next_1:
    CMP     CL, n
    JNB     next_2

کد:
    INC     BH
    CMP     BH, n
    JBE     loop_2
 

aida-joon

New Member
ممنون
تغییراتو دادم اما وقتی مثلا عدد 5 میزدم باز تا 10 حساب میکرد
تو قسمت دسیمال به جای تقسیم بر 10 تقسیم بر n گذاشتم اما خروجی ؟ > < ... میداد
:rose:
 

the_king

مدیرکل انجمن
ممنون
تغییراتو دادم اما وقتی مثلا عدد 5 میزدم باز تا 10 حساب میکرد
تو قسمت دسیمال به جای تقسیم بر 10 تقسیم بر n گذاشتم اما خروجی ؟ > < ... میداد
:rose:

من که دو جایی که باید 10 رو به n تغییر می دادید رو نشون دادم، کد get_number رو که نباید عوض کنید،
اون تقسیم بر 10 برای تبدیل رشته به عدد در مبنای 10 است، وقتی اون رو تغییر می دهید در واقع مبنای
عدد نمایش داده شده رو تغییر می دهید.
 

aida-joon

New Member
بله من اشتباه کرده بودم.
میشه بدون دستور mul هم جدول ضرب n*n درست کرد؟
من یک حلقه افزایشی که از یک شروع میشه تا n گذاشتم.به ازای هر سطر گام افزایش برابر شماره هر سطر و در حلقه داخلی از 1 تا n ، n بار تکرار میشه
اما جواب n*n نمیشه
:rose:
 

the_king

مدیرکل انجمن
بله من اشتباه کرده بودم.
میشه بدون دستور mul هم جدول ضرب n*n درست کرد؟
من یک حلقه افزایشی که از یک شروع میشه تا n گذاشتم.به ازای هر سطر گام افزایش برابر شماره هر سطر و در حلقه داخلی از 1 تا n ، n بار تکرار میشه
اما جواب n*n نمیشه
:rose:

کد زیر رو در برنامه پیدا کنید :
کد:
    MOV     AL, BL
    MUL     BH
    MOV     AH, AL
    CALL    decimalprint
    MOV     CL, AL

و با این کد ها تعویض اش کنید :
کد:
    MOV     AH, 0
    MOV     CL, BH
    MOV     CH, 0
loop_5:
    ADD     AH, BL
    LOOP    loop_5
    CALL    decimalprint
    MOV     CL, AH
 

aida-joon

New Member
این کد نتیجه رو نمیده!!!!!!!!!!:rose:
کد:
.MODEL SMALL
.STACK
.DATA 
    msg1 db "get_number:" ,"$"
    msg DB 13,10,"Press any key to continue.",13,10,"$"
    n DB ? 
.CODE
.STARTUP  
    mov ax,@data
    mov ds,ax
    mov ah,09h
    lea dx,msg1
    int 21h
    mov ah,08h
    int 21h
    mov n,al
    MOV     BH, 1
loop_1:
    MOV     BL, 1
loop_2:
    MOV     AH, 0
    MOV     CL, BH
    MOV     CH, 0
loop_5:
    ADD     AH, BL
    LOOP    loop_5
    CALL    decimalprint
    MOV     CL, AH
    MOV     AH, 2
    MOV     DL, " "
    INT     21H
    CMP     CL,100
    JNB     next_1
    INT     21H
next_1:
    CMP     CL, n
    JNB     next_2
    INT     21H
next_2:
    INC     BL
    CMP     BL, n
    JBE     loop_2
    MOV     DL, 13
    INT     21H
    MOV     DL, 10
    INT     21H
    INC     BH
    CMP     BH, n
    JBE     loop_1
    MOV     AH, 9
    LEA     DX, msg
    INT     21H
    MOV     AH, 8
    INT     21H
    .EXIT

decimalprint:
    PUSH    AX
    PUSH    BX
    PUSH    CX
    PUSH    DX
    MOV     CX, 0
    MOV     AL, AH
    MOV     BL, 10
loop_3:
    MOV     AH, 0
    DIV     BL
    PUSH    AX
    INC     CX
    CMP     AL, 0
    JNE     loop_3
    MOV     AH, 2
loop_4:
    POP     DX
    MOV     DL, DH
    ADD     DL, "0"
    INT     21H
    LOOP    loop_4
    POP     DX
    POP     CX
    POP     BX
    POP     AX
    RET
ENd
 

the_king

مدیرکل انجمن
1) کد های زیر اضافی هستند، STARTUP. همه تنظیمات رجیستر ها را بطور خودکار انجام میده :
کد:
    mov ax,@data
    mov ds,ax

2) سرویس 8 از وقفه 21 یک کاراکتر از ورودی دریافت می کنه، نه یک عدد. مثلا اگه کلید 1 رو فشار دهید، کد 49 رو در
AL قرار میده، نه عدد 1 رو :
کد:
    mov ah,08h
    int 21h
    mov n,al

بایستی پیش از قرار دادن اون کاراکتر در n به عدد تبدیلش اش کنید :
کد:
    mov ah,08h
    int 21h
    SUB AL, "0"
    mov n,al

3) زمانی که کلیدی را از صفحه کلید دریافت می کنید، بطور خودکار به ابتدای سطر بعدی نمی روید، به همین جهت
اگه بخواهید بدون اضافه کردن کدی برای رفتن به ابتدای سطر بعدی ادامه دهید، نمایش جدول ضرب بهم می ریزه :

کد:
    mov ah,08h
    int 21h
    SUB AL, "0"
    mov n,al
    MOV AH, 2
    MOV DL, 13
    INT 21h
    MOV DL, 10
    INT 21h

کد ویرایش شده :
کد:
.MODEL SMALL
.STACK
.DATA 
	msg1 db "get_number:" ,"$"
	msg DB 13,10,"Press any key to continue.",13,10,"$"
	n DB ? 
.CODE
.STARTUP	
	MOV	AH, 09h
	LEA	DX, msg1
	INT	21h
	MOV	AH, 08h
	INT	21h
	SUB	AL, "0"
	MOV	n, AL
	MOV	AH, 2
	MOV	DL, 13
	INT	21H
	MOV	DL, 10
	INT	21H
	MOV	BH, 1
loop_1:
	MOV	BL, 1
loop_2:
	MOV	AH, 0
	MOV	CL, BH
	MOV	CH, 0
loop_5:
	ADD	AH, BL
	LOOP	loop_5
	CALL	decimalprint
	MOV	CL, AH
	MOV	AH, 2
	MOV	DL, " "
	INT	21H
	CMP	CL,100
	JNB	next_1
	INT	21H
next_1:
	CMP	CL, 10
	JNB	next_2
	INT	21H
next_2:
	INC	BL
	CMP	BL, n
	JBE	loop_2
	MOV	DL, 13
	INT	21H
	MOV	DL, 10
	INT	21H
	INC	BH
	CMP	BH, n
	JBE	loop_1
	MOV	AH, 9
	LEA	DX, msg
	INT	21H
	MOV	AH, 8
	INT	21H
	.EXIT

decimalprint:
	PUSH	AX
	PUSH	BX
	PUSH	CX
	PUSH	DX
	MOV	CX, 0
	MOV	AL, AH
	MOV	BL, 10
loop_3:
	MOV	AH, 0
	DIV	BL
	PUSH	AX
	INC	CX
	CMP	AL, 0
	JNE	loop_3
	MOV	AH, 2
loop_4:
	POP	DX
	MOV	DL, DH
	ADD	DL, "0"
	INT	21H
	LOOP	loop_4
	POP	DX
	POP	CX
	POP	BX
	POP	AX
	RET
END
 

جدیدترین ارسال ها

بالا