معرفی اسمبلر برای 8086

emad_67

Member
با سلام
می خواست یه اسمبلر که بتونم توش کد های اسمبلی cpu 8086 رو بنویسم بهم معرفی کنید.
من از readasm ، fasm استفاده کردم ولی همش ارور میدن موقع اجرا.
زیاد مهم نیست که یه محیط حرفه ای باشه یا نباشه فقط می خوام یه چیزی باشه که یه کدی مثل این رو بتونم اجرا کنم.
کد:
stacksg segment 'stack'
db 32 dup('stack')
stacksg ends

datasg segment 'data'
msg db 'this is test','$'
datasg ends

codesg segment para 'code'
main proc far
assume cs:codesg,ds:datasg,ss:stacksg
push ds
push 0
mov ax,datasg
mov ds,ax
call cls

mov ah,4ch
int 21h
main endp

cls proc
move ah,6h
mov al,25
mov ch,0
mov cl,0
mov dh,24
mov dl,79
mob bh,0Fh
int 10h
ret
cls endp
codesg ends
end main
با تشکر
 

hoax3r

New Member
فکر میکنم emu8086 برای این کار شما خوب باشه، این برنامه از fasm استفاده میکنه
 

the_king

مدیرکل انجمن
هیچ کامپایلری قادر به کامپایل کردن کدی که اشتباه تایپ شده نیست.
کلمات اشتباه ویرایش شده و اضافه شده را در کدتان مشخص کردم. همچنین به دلیل استفاده از کد push 0 بایستی نوع پردازنده
286 به بعد باشد. پردازنده های 8086 قادر به push کردن یک مقدار ثابت نیستند و این فرمان
در پردازنده های 286 به بعد موجود است.
مشخص کردن پردازنده با اضافه کردن یک سطر 386. انجام شد.
همچنین مدل حافظه بایستی مشخص شود، نوع مناسب این برنامه small است.
کد زیر در اسمبلر مشهور MASM محصول Microsoft قابل کامپایل است :

کد:
[B].model small[/B]
[B].386[/B]

stacksg segment 'stack'
db 32 dup('stack')
stacksg ends

datasg segment 'data'
msg db 'this is test','$'
datasg ends

codesg segment para 'code'
main proc far
assume cs:codesg,ds:datasg,ss:stacksg
push ds
push 0
mov ax,datasg
mov ds,ax
call cls

mov ah,4ch
int 21h
main endp

cls proc
[B]mov ah,6h[/B]
mov al,25
mov ch,0
mov cl,0
mov dh,24
mov dl,79
[B]mov bh,0Fh[/B]
int 10h
ret
cls endp
codesg ends
end main
 

emad_67

Member
ممنون جناب the_king
من masm رو دانلود کردم از میکروسافت ولی موقع نصب می گه که باید c++ express نصب باشه. این c++ express منم نمیدونم چیه.
اگه c++ 2005 رو نصب کنم حل میشه؟
الان همون کد اول رو که گذاشته بودم با emu8086 اجرا کردم و مشکلی نداشت.
آیا تعریف مدل حافظه الزامی هست؟ چون من وقتی اونو تعریف هم نمیکنم برنامه اجرا میشه. و اگه مدل رو تعریف نکنیم، به صورت پیشفرض هر سگمنت 64 کیلوبایت در نظر گرفته نمیشه؟

یه سوال دیگه اینکه در ابتدای برنامه استک سگمنت رو تعریف کردیم:
کد:
stacksg segment 'stack'
db 32 dup('stack')
stacksg ends
حالا می خواستم بدونم ببینم این قسمت:
کد:
db 32 dup('stack')
فقط برای در نظر گرفتن حافظه برای استک سگمنت هست یا نه؟ و باعث میشه که 5*32 بایت حافظه گرفته بشه؟ (5 همون طول رشته "stack" است)

سوالم بعدیم هم اینه که در کد بالا این قسمت رو داریم:
کد:
push ds
push 0
mov ax,datasg
mov ds,ax
میخواستم بدونم این قسمت اصلا چیکار میکنه؟ با توجه به اینکه با دستور assume نام سگمنت ها رو به ثبات ها نسبت دادیم، پس چرا دوباره توی این کد مجددا دیتا سگمت رو به ثبات ds نسبت داده؟
push ds و push 0 هم اگه بگی چیکار میکنن ممنون میشم.
با تشکر
 

the_king

مدیرکل انجمن
نسخه ای که شما داونلود کرده اید MASM رایگان ویرایش 32 بیتی برای ویندوز است وگرنه MASM یک نرم افزار رایگان نیست
که بتوانید به سادگی از سایت مایکروسافت داونلود کنید.
آخرین نسخه مستقل MASM سازگار با DOS ویرایش 6.1 آن بود و نسخه های بعدی بصورت ضمیمه سایر کامپایلر های
مایکروسافت عرضه شده اند و خود MASM از چرخه ساپورت مایکروسافت خارج شده است.
MASM را می توانید از این لینک دریافت کنید (12.8 مگابایت است) :

MASM 6.1

لینک مستقیم داونلود masm611.zip :
Download masm611.zip

هر سگمت حداکثر 64 کیلوبایت است و این مساله ارتباطی با model حافظه ندارد. مساله تعداد و نوع ارجاع میان سگمنت ها
است. مثلا در یک برنامه که حجم کد اش 5 کیلوبایت هم نیست، می توانید ارجاع کد درون آنرا far تعریف کنید.
کامپایلر مطیع درخواست برنامه نویس است مخصوصا در زبان اسمبلی که همه چیز باید مطابق با میل برنامه نویس باشد.

اینکه حافظه stack را با چه پر کنید اهمیتی ندارد و آن شیوه عجیبی که بکار برده شده هم معمول نیست.
مخصوصا که در سیستم عاملهای امروزی سعی کنید کمتر 1024 بایت را به stack اختصاص ندهید.
مقدار 1024 بایت پیشفرض stack. در کامپایلر های مایکروسافت است.
در کامپایلر های مدرن تعریف سگمنت ها می تواند بسیار ساده تر انجام شود گو اینکه با همه اسمبلرها سازگاری ندارد :

کد:
.model small
.data

mymsg db "Hello.$"

.code
.startup

mov ah, 9
lea dx, mymsg
int 21h

.exit
[B].stack 2048[/B]
end

به همین سادگی، طول سگمنت stack را هم بدین شکل 2048 بایت تعریف کرده ام.

در زمان اجرا شدن یک فایل اجرایی اسمبلی تمامی تغییراتی که در رجیستر ها انجام می شود تحت کنترل برنامه نویس است
و برعکس زبانهای دیگر هیچ عملی انجام نمی شود مگر آنکه شما کدش را اضافه کنید.

assume به کامپایلر می فهماند که اگر در کد من ارجاعی به محلی از حافظه شد باید از چه segment register ای استفاده کند.
یعنی شما باید کامپایلر را از مکان فعلی رجیستر ها آگاه کنید وگرنه خودش متوجه تغییر آنها نخواهد شد.
مثلا وقتی شما به قسمتی از سگمنت داده خود ارجاعی دارید، کامپایلر هیچ پیشفرضی در مورد اینکه باید از cs یا ds یا es و ...
استفاده کند ندارد. اما فراموش نکنید که assume به تنهایی هیچ مقداری را به رجیستر ها اختصاص نمی دهد.

حالا وقتی برنامه شما اجرا می شود رجیستر ds به یک جایی از حافظه اشاره کرده است، اما قصد ما این است که به سگمنت
داده ما اشاره کند. اما طبق اصول فراخوانی برنامه های exe در dos باید مقدار قبلی ds حفظ شود بدین صورت که در هنگام
خروج از برنامه سیستم عامل با یک pop ds مقدار قبلی را دریافت می کند برای همین آن push ds لازم است.
push 0 هم جزو موارد مورد نیاز برای dos است.

بجای این کد ها می توانید از startup استفاده کنید.
بجای استفاده از وقفه خروج هم می توانید از exit. استفاده کنید.
 

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

بالا