سینا بختیاری _ استاد راهنما : داوود یعقوبی تبار _ دانشگاه صدرا _ 951215271048
مقاله ی مختصر در مورد پروژه ساده ماشین حساب به زبان اسمبلی
در مورد پروژه که یک ماشین حساب ساده هستش ی توضیح مختصر میدیم و بعد میریم سراغ توضیح بعضی از دستورات اصلی داخل برنامه
ماشین حساب ما فقط 4 عمل اصلی یعنی (+ و - و * و /) رو برای ما انجام میده
بعد از اجرا شدن برنامه، دو عدد به همراه یکی از عملگرهای مشخص شده از کاربر گرفته می شود. بعد از فشار دادن کلید Enter برنامه نتیجه عملیات را محاسبه کرده و در خروجی چاپ می کند.
این برنامه با استفاده از برنامه emu8086 نوشته شده است
در این برنامه ما حداکثر تعداد ارقامی که میتونیم وارد کنیم 5 عدد هستش و اگر عدد 6ام رو وارد کنیم خود برنامه میاد اون رو برای ما حذف میکنه و اینکه میتونیم اعداد منفی رو به برنامه بدیم و در خروجی عدد منفی هم هم داشته باشیم (برای ضرب اعداد علامتدار از imul و تقسیم از idiv استفاده شده )
و یک مورد دیگه اینکه اگر تقسیم ما باقیمانده داشته باشد باقیمانده رو به ما نشون نمیدهد و فقط قسمت صحیح رو نشون میده و برای باقیمانده and somthing رو جلوی اون عدد صحیح قرار میده.
خب از انجایی که زبان اسمبلی یک زبان شیء گرا نیستش ما مجبوریم تمام حالات رو در نظر بگیریم و کر هر قسمت رو به صورت جدا وارد بکنیم تا برنامه به درستی اجرا شود.
میرسیم به قسمت توضیح برخی از کد های برنامه
exit macro ماکروی خروج از برنامه
mov ax,4c00h کد خروج
int 21h
endm
;----------------------
pushreg macro ماکروی ذخیره اطلاعات ثبات ها در پشته
push ax
push bx
push cx
push dx
push si
push di
endm
;----------------------
popreg macro ماکروی بازیابی اطلاعات ثبات ها در پشته
pop di
pop si
pop dx
pop cx
pop bx
pop ax
endm
;----------------------
gets macro str ماکروی گرفتن اطلاعات از کاربر
pushreg
lea dx,str ادرس رشته در اینجا توی دی ایکس ذخیره میشه
mov ah,0ah تابع گرفتن اطلاعات
int 21h
popreg
endm
;----------------------
prints macro str چاپ اطلاعات
pushreg
lea dx,str
mov ah,09h
int 21h
popreg
endm
;----------------------
getc macro گرفتن یک کاراکتر از کاربر
pushreg
mov ah,01h
int 21h
popreg
endm
;----------------------
itoa macro n,str,len تبدیل عدد به رشته
local while
pushreg
lea di,str
mov dl,len
mov dh,0
add di,dx
mov byte ptr[di],'$'
mov al,n
mov ah,0
mov cl,10
while: dec di
div cl
add ah,48
mov [di],ah
mov ah,0
cmp al,0
jne while
popreg
endm
;----------------------
atoi macro str,n,len تبدیل رشته به عدد
local while1
pushreg
lea di,str
mov ax,0
mov bx,10
mov ch,0
mov cl,len
while1: mul bl
mov dx,0
mov dl,byte ptr[di]
sub dx,48
add ax,dx
inc di
loop while1
mov n,al
popreg
endm
;----------------------
.model small
.stack 64
.data
strlist1 label byte تعریف برچسب برای ورودی عدد اول
max1 db 5
len1 db ?
str1 db 6 dup('$')
strlist2 label byte تعریف برچسب برای ورودی عدد دوم
max2 db 5
len2 db ?
str2 db 6 dup('$')
strlist3 label byte تعریف برچسب برای ورودی عملگر
max3 db 2
len3 db ?
op db 2 dup('$')
str3 db 5 dup(' '),'$' نتیجه در اینجا ذخیره میشه
msgn1 db 10,13,"Enter Number1:$" اینها پیفام ها هستند 10و13 یعنی یه خط برو پایین
msgn2 db 10,13,"Enter Number2:$"
msgop db 10,13,"Enter op(+ , - , * , /):$"
msgR db 10,13,"Result:$"
n1 db 0 رشته اول بعد اینکه به عدد تبدیل شد در این متغیر ذخیره میشه
n2 db 0 رشته دوم بعد اینکه به عدد تبدیل شد در این متغیر ذخیره میشه
R db 0 حاصل اینجا ذخیره میشه
.code
main proc far
mov ax,@data
mov ds,ax
prints msgn1 چاپ پیغام دریافت عدد اول
gets strlist1 گرفتن عدد اول
prints msgn2 چاپ پیغام دریافت عدد دوم
gets strlist2 گرفتن عدد دوم
prints msgop چاپ پیغام دریافت عملگر
gets strlist3 گرفتن عملگر
atoi str1,n1,len1 تبدیل رشته عددی اول به عدد و قرار دادن آن در ان1
atoi str2,n2,len2 تبدیل رشته عددی دوم به عدد و قرار دادن آن در ان2
cmp op,'+' مقایسه عمگر با جمع
jne skipplus برابر نباشه به پر و جمع رو رد کن
mov al,n1 عدد اول در ا ال
add al,n2 جمع ا ال با ان 2 و ذخیره در ا ال
mov R,al حاصل رو به ار بده
jmp endcalc پرش کن به اخر و نتیجه رو اونجا چاپ کن
skipplus:
cmp op,'-'
jne skipmin برابر نباشه به پر و تفریق رو رد کن
mov al,n1 عدد اول در ا ال
sub al,n2 تفریق ا ال با ان 2 و ذخیره در ا ال
mov R,al حاصل رو به ار بده
jmp endcalc پرش کن به اخر و نتیجه رو اونجا چاپ کن
skipmin:
cmp op,'*'
jne skipmul برابر نباشه به پر و ضربرو رد کن
mov ah,0 ا اچ ضفر میشه چون ضرب و تقسیم اینو هم استفاده می کنه
mov al,n1 عدد اول در ا ال
mul n2 ا ال با ان 2 ضرب شده و در ا ال قرار میگیره
mov R,al حاصل از ا ال میره به ار
jmp endcalc پرش کن به اخر و نتیجه رو اونجا چاپ کن
skipmul:
cmp op,'/'
jne skipdiv برابر نباشه به پر و تقسیم رو رد کن
mov ah,0 ا اچ ضفر میشه چون ضرب و تقسیم اینو هم استفاده می کنه
mov al,n1 عدد اول در ا ال
div n2 ا ال با ان 2 تقسیم میشه و جواب در ا ال میره
mov R,al از ا ال جواب رو بر میداره میریزه به ار
jmp endcalc پرش کن به اخر و نتیجه رو اونجا چاپ کن
skipdiv:
endcalc:
itoa al,str3,5 نتیجه رو که عدد است به رشته تبدیل می کنه بعد میزاره به استر 3
prints msgR پیغام چاپ نتیجه
prints str3 حاصل رو چاپ می کنه
getc کلید میگیره
exit پایان
main endp
end main