سوال اسمبلی

aida-joon

New Member
سلام
برنامه زیر برای چاپ کلمات رشته در سطر های مجزا است.استادم سر کلاس نوشته.اما هنگام اجرا روی خط زیر خطامیده .لطفا راهنمایی کنید

کد:
DataSg Segment Para
StrList Label Byte
Max Db 20
Len Db ?
Buffer Db 20Dup(' $ ')
DataSg EndS

CodSeg SegMent Para


Lea DX , StrList
Mov AH, 0AH
Int 21H

Lea Dx , Buffer
Mov Ch , 0
Add Bx ,Cx
Mov Cl ,0
P1 :

Mov DH, Cl
Mov Dl , 0
Mov AH , 02H
Int 10H


Mov dl ,[DX]
Mov Ah ,02H
Int 21H
Inc Cl
Inc Dx
Cmp Cl , Len
JE P1
Mov Ax , 4C00H
Int 21H
Main EndP
CodSeg EndSeg
End Main
 

the_king

مدیرکل انجمن
سلام
برنامه زیر برای چاپ کلمات رشته در سطر های مجزا است.استادم سر کلاس نوشته.اما هنگام اجرا روی خط زیر خطامیده .لطفا راهنمایی کنید
اگه در یادداشت برداری از تخته سیاه یا تخته سفید اشتباه کرده اید که هیچ، وگرنه استادتون در اصول مقدماتی
اسمبلی 8086 مشکل جدی داره.
1) آدرس هایی که با رجیستر ها بصورت غیر مستقیم مشخص می شوند توسط SI و DI و BX مشخص می گردند
و DX برای این منظور قابل استفاده نیست.
به همین جهت فرمان زیر کلا اشتباه است :
کد:
Mov dl ,[DX]

2) در ضمن زمانی که یک رجیستر را برای اشاره کردن به یک آدرسی بکار خواهید برد، نوشتن مقدار دیگری در آن باعث
تخریب شدن آدرس موجود خواهد شد، نوشتن مقدار در DL مقدار DX را تغییر می دهد :
کد:
Mov dl ,[DX]
.
.
.
Inc Dx

و همچنین :
کد:
Lea Dx , Buffer
.
.
.

Mov DH, Cl
Mov Dl , 0

3) در کد نوشته شده که Add Bx ,Cx . در حالی که نه مقدار BX مشخص است و نه مقدار CL . در نتیجه یک مقدار
نا مشخص را با یک مقدار نامشخص دیگر جمع می کنید که نتیجه یک مقدار نامشخص دیگر است.

4) در شرط حلقه نوشته شده که :
کد:
Cmp Cl , Len
JE P1
یعنی اگر CL به مقدار طول رشته LEN رسیده بود، به ابتدای حلقه پرش کن، وگرنه کار برنامه خاتمه می یابد.
شرطی که اشتباه است، این شرط می بایستی شرط خاتمه اجرای حلقه می بود، نه شرط ادامه اجرای آن.
این شرط دقیقا متعارف این عبارت است : اگر رشته یک کاراکتر بود، یک کاراکتر 13 بعد از آن را هم نمایش بده
و اگر بیش از یک کاراکتر بود، فقط همان کاراکتر اول را نشان بده و از بقیه صرف نظر کن.


این کد درسته :
کد:
.MODEL	SMALL
.DATA 
strlist	LABEL	BYTE
	max	DB 20
	len	DB ?
	buffer	DB 20 DUP("$")
	msg	DB 13, 10, "Please press any key to continue.", 13, 10, "$"
.CODE
.STARTUP
.386
	MOV	AH, 0Ah
	LEA	DX, strlist
	INT	21h
	MOV	CL, len
	MOV	CH, 0
	CMP	CX, 0
	JZ	finish
	MOV	AH, 2
	LEA	BX, buffer
loop_1:
	MOV	DL, 13
	INT	21h
	MOV	DL, 10
	INT	21h
	MOV	DL, [BX]
	INT	21h
	INC	BX
	LOOP	loop_1
finish:
	MOV	AH, 9
	LEA	DX, msg
	INT	21h
	MOV	AH, 8
	INT	21h
	.EXIT
.STACK
END

کد کامل برنامه و به همراه فایل اجرایی exe ضمیمه این پست می باشد.
 

پیوست ها

  • c.zip
    629 بایت · بازدیدها: 5

aida-joon

New Member
تشکر

مسلما نباید اشکال از استاد باشه
من جزوه رو کپی کردم.از توضیحات ممنون تازه متوجه شدم.
تنها یه سوال :
اگه میخواستیم به جای کاراکترها کلمات رشته به همین صورت چاپ بشن باید چیکار کرد؟
میشه یه حلقه گذاشت که اگه یه اسپیس رسید بره خط بعد؟
:rose::rose::rose::rose::rose::rose::rose::rose:
 

the_king

مدیرکل انجمن
مسلما نباید اشکال از استاد باشه
من جزوه رو کپی کردم.از توضیحات ممنون تازه متوجه شدم.
تنها یه سوال :
اگه میخواستیم به جای کاراکترها کلمات رشته به همین صورت چاپ بشن باید چیکار کرد؟
میشه یه حلقه گذاشت که اگه یه اسپیس رسید بره خط بعد؟
:rose::rose::rose::rose::rose::rose::rose::rose:

بله، صرفا باید یکسری تغییرات در نحوه نمایش سایر کاراکتر ها هم بدهید :
کد:
.MODEL	SMALL
.DATA 
strlist	LABEL	BYTE
	max	DB 20
	len	DB ?
	buffer	DB 20 DUP("$")
	msg	DB 13, 10, "Please press any key to continue.", 13, 10, "$"
.CODE
.STARTUP
.386
	MOV	AH, 0Ah
	LEA	DX, strlist
	INT	21h
	MOV	CL, len
	MOV	CH, 0
	CMP	CX, 0
	JZ	finish
	MOV	AH, 2
	LEA	BX, buffer
next_1:
	MOV	DL, 13
	INT	21h
	MOV	DL, 10
	INT	21h
loop_1:
	MOV	DL, [BX]
	INC	BX
	CMP	DL, " "
	JNE	next_2
	LOOP	next_1
	JMP	finish	
next_2:
	INT	21h
	LOOP	loop_1
finish:
	MOV	AH, 9
	LEA	DX, msg
	INT	21h
	MOV	AH, 8
	INT	21h
	.EXIT
.STACK
END

کد کامل برنامه به همراه فایل اجرایی exe ضمیمه این پست می باشد.
 

پیوست ها

  • d.zip
    667 بایت · بازدیدها: 4

aida-joon

New Member
تشکر

در برنامه اول که کاراکترها رو در سطرهای مجزا چاپ میکرد:
من میخواهم تعداد کاراکتر ها یی که در هر سطر چاپ میشن متناسب با شماره همون سطر باشه
برای اینکار یه حلقه افزایشی گذاشتم .اما هنگام اجرا یک حلقه بینهایت ایجاد شد.لطفا منو راهنمایی کنید.
یک سوال دیگه اینکه آیا فاصله تو اسمبلی مهم هست یا نه؟
:rose:
 

the_king

مدیرکل انجمن
در برنامه اول که کاراکترها رو در سطرهای مجزا چاپ میکرد:
من میخواهم تعداد کاراکتر ها یی که در هر سطر چاپ میشن متناسب با شماره همون سطر باشه
برای اینکار یه حلقه افزایشی گذاشتم .اما هنگام اجرا یک حلقه بینهایت ایجاد شد.لطفا منو راهنمایی کنید.
یک سوال دیگه اینکه آیا فاصله تو اسمبلی مهم هست یا نه؟
:rose:

چون رجیستر CX قبلا مورد استفاده قرار گرفته امکان اینکه مجددا به همون نحو برای منظور دیگه ای مثل
شمردن تعداد کاراکتر هایی که در هر سطر چاپ می شوند، استفاده کنید نیست، باید از PUSH و POP
برای نگهداری مقدار CX در بین این دو کاربرد مجزا استفاده کنید :
کد:
linenumber DW 1
.
.
.
loop_1:
.
.
.
PUSH CX
MOV CX, linenumber
INC linenumber
loop_2:
.
.
.
LOOP loop_2
POP CX
.
.
.
LOOP loop_1
 

aida-joon

New Member
ممنون

به این صورت کدو بازنویسی کردم ولی باز نتونستم !!!!!!!!
میشه یکم بیشتر توضیح بدید
:rose:
 

the_king

مدیرکل انجمن
به این صورت کدو بازنویسی کردم ولی باز نتونستم !!!!!!!!
میشه یکم بیشتر توضیح بدید
:rose:

lineno شماره سطر است، که از 1 شروع می شود. هر گاه که نمایش یک سطر تمام شد، یک واحد آنرا
افزایش خواهیم داد.

CX در حلقه loop_1 برای شمردن تعداد کاراکتر هایی است که هنوز از رشته چاپ نشده. مثلا اگر رشته 10 کاراکتری
را چاپ می کنیم در همان ابتدا CX در حلقه loop_1 برابر 10 خواهد بود. هر بار که یک سطر از رشته را
نمایش دهیم، به تعداد کاراکتر های نمایش داده شده از این CX کسر می کنیم.

CX در حلقه loop_2 برای شمردن تعداد کاراکتر هایی است که هنوز از سطر فعلی چاپ نشده اند، مثلا اگر رشته
10 کاراکتری را چاپ می کنیم و به ابتدای سطر سوم رسیده ایم، CX برابر 3 خواهد بود. CX در ابتدای هر سطر
معمولا برابر lineno خواهد بود که شماره سطر است، مگر در حالتی که در سطر آخر باشیم و رشته ورودی کوچکتر از
آن باشد که تمام سطر آخر را پر کند. مثلا اگر یک رشته 8 کاراکتری را چاپ کنیم، در سطر چهارم فقط می توان
دو کاراکتر را نمایش داد، نه چهار کاراکتر.

ما پیش از آنکه CX را به حلقه loop_2 بسپاریم، مقدارش را در یک رجیستر (DI) ذخیره می کنیم تا بدانیم در هر سطر
دقیقا چند کاراکتر را نمایش داده ایم. بعد از آنکه حلقه loop_2 به پایان رسید، این مقدار DI را از تعداد کاراکتر های
باقیمانده از رشته (CX) کسر می کنیم تا ببینیم هنوز چند کاراکتر برای نمایش در سطر های بعدی باقی مانده است.
استفاده کردن از این DI بجای lineno (چون در حالت عادی در هر سطر به تعداد شماره همان سطر کاراکتر
خواهیم داشت) ما را مطمئن می سازد که اگر رشته کاربر به اندازه کافی طولانی نبود، کاراکتر ناخواسته ای چاپ
نشود و همچنین مقدار CX منفی نشود. منفی شدن مقدار CX موجب تکرار حلقه loop_1 برای هزاران بار دیگر
خواهد شد که صفحه نمایش را به هم خواهد ریخت.


کد:
.MODEL	SMALL
.DATA 
strlist	LABEL	BYTE
	max	DB 20
	len	DB ?
	buffer	DB 20 DUP("$")
	msg	DB 13, 10, "Please press any key to continue.", 13, 10, "$"
	lineno	DW 1
.CODE
.STARTUP
.386
	MOV	AH, 0Ah
	LEA	DX, strlist
	INT	21h
	MOV	CL, len
	MOV	CH, 0
	CMP	CX, 0
	JZ	finish
	MOV	AH, 2
	LEA	BX, buffer
loop_1:
	MOV	DL, 13
	INT	21h
	MOV	DL, 10
	INT	21h
	PUSH	CX
	CMP	CX, lineno
	JLE	next_1
	MOV	CX, lineno
next_1:
	MOV	DI, CX
loop_2:
	MOV	DL, [BX]
	INT	21h
	INC	BX
	LOOP	loop_2
	POP	CX
	INC	lineno
	SUB	CX, DI
	CMP	CX, 0
	JNZ	loop_1
finish:
	MOV	AH, 9
	LEA	DX, msg
	INT	21h
	MOV	AH, 8
	INT	21h
	.EXIT
.STACK
END
 

behnaz m

New Member
سلام اگر بخواهم یک برنامه با c++ بسازم که چند عدد از ورودی گرفته و مجموع مربعات ان را محاسبه کند و به همراه ان تعداد اعداد را چاپ کند باید چیکار کنم
 

the_king

مدیرکل انجمن
سلام اگر بخواهم یک برنامه با c++ بسازم که چند عدد از ورودی گرفته و مجموع مربعات ان را محاسبه کند و به همراه ان تعداد اعداد را چاپ کند باید چیکار کنم

یک سوال را چند بار می پرسید؟
بایستی بجای اینکه یک سوال را چند و آن هم در یک تاپیک نامربوط (اسمبلی) بپرسید، به تاپیک قبلی که خودتان
نوشته بودید مراجعه کنید. پاسخ تان را آنجا داده بودم.
 

behnaz m

New Member
یک سوال را چند بار می پرسید؟
بایستی بجای اینکه یک سوال را چند و آن هم در یک تاپیک نامربوط (اسمبلی) بپرسید، به تاپیک قبلی که خودتان
نوشته بودید مراجعه کنید. پاسخ تان را آنجا داده بودم.

چون عضو جدید هستم اول نرفتم جواب و ببینم
 

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

بالا