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

hassancd

Active Member
سلام دوستان
من میخوام در اسمبلی برنامه جمع دو عدد چند رقمی را بنویسم باید چیکار کنم
اگه میشه راهنماییم کنید
برنامه تکرقمیش رو نوشتم و لی برای چند رقمیش رو نمی دونم باید چیکار کنم ممنون میشم
با تشکر
 

the_king

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

برای دریافت یک عدد 16 بیتی (بین 0 الی 65535) از کاربر از کد زیر استفاده کنید که توسط call فراخوانی می شود
و عدد مورد نظر را در BX می خواند :
کد:
.DATA
    number  DB 5
            DB ?
            DB 5 DUP (?)
.CODE

get_number:
    PUSH    AX
    PUSH    CX
    PUSH    DX
    MOV     AH, 0ah
    LEA     DX, number
    INT     21h
    MOV     BX, -1
    MOV     CL, number[1]
    CMP     CL, 0
    JZ      next_4
    MOV     AH, 2
    MOV     DL, 13
    INT     21h
    MOV     DL, 10
    INT     21h
    MOV     CH, 0
    LEA     SI, number[2]
    MOV     DI, 10
    MOV     BX, 0
loop_2:
    MOV     AL, [SI]
    CMP     AL, "0"
    JB      next_3
    CMP     AL, "9"
    JA      next_3
    SUB     AL, "0"
    MOV     AH, 0
    XCHG    AX, BX
    MUL     DI
    ADD     BX, AX
next_3:
    INC     SI
    LOOP    loop_2
next_4:
    POP     DX
    POP     CX
    POP     AX
    RET

به عنوان مثال کد زیر دو عدد از ورودی خوانده و در AX جمع کرده و قرار می دهد :
کد:
   CALL    get_number
   MOV     AX, BX
   CALL    get_number
   ADD     AX, BX

برای مثال تکمیلی به تاپیک زیر مراجعه کنید :

محاسبه میانگین چند عدد در زبان اسمبلی

برای نمایش یک عدد 16 بیتی روی صفحه نمایش از کد زیر استفاده کنید که بایستی توسط call فراخوانی شود و عدد
موجود در AX را نمایش می دهد :
کد:
print_dec_ax:
    PUSH    AX
    PUSH    BX
    PUSH    CX
    PUSH    DX
    MOV     CX, 0
    MOV     BX, 10
loop_1:
    MOV     DX, 0
    DIV     BX
    PUSH    DX
    INC     CX
    CMP     AX, 0
    JNE     loop_1
    MOV     AH, 2
loop_2:
    POP     DX
    ADD     DL, "0"
    INT     21H
    LOOP    loop_2
    POP     DX
    POP     CX
    POP     BX
    POP     AX
    RET

به عنوان مثال کد زیر عدد 12345 را نمایش می دهد :
کد:
    MOV     AX, 12345
    CALL    print_dec_ax

برای مثال تکمیلی به تاپیک زیر مراجعه کنید :

نمایش اعداد 16 بیتی بصورت مبنای 10 در زبان اسمبلی
 

hassancd

Active Member
دوست گرامی خیلی کمکم کردید
فقط نمیدونم چرا لینکهات برام باز نمیشه اگه میشه دوباره برام بزار

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

the_king

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

نکاتی راجع به دسترسی های محدود و فعال سازی اکانت :

کد:
http://forum.majidonline.com/showthread.php?t=143628
 

hassancd

Active Member
راستی من نمی خواستم از pop , push استفاده کنم نمی دونید چیکار کنم اگه میشه بیشتر راهنماییم کنید ممنون
 

the_king

مدیرکل انجمن
راستی من نمی خواستم از pop , push استفاده کنم نمی دونید چیکار کنم اگه میشه بیشتر راهنماییم کنید ممنون

PUSH و POP ها برای این منظور بکار رفته اند که مقادیر قبلی رجیستر ها را حفظ کنند، مثلا اگر قبل از نمایش یک عدد
در نمایشگر مقدار AX برابر 12 باشد، بعد از فراخوانی print_dec_ax مقدار AX همچنان 12 باشد و عوض نشود.

می توانید بجای PUSH و POP در قسمت DATA. داده هایی را از نوع DW تعریف کنید و مقادیر را در آنها ذخیره کنید.

کد:
.MODEL	SMALL
.DATA 
	msg1	DB 13, 10, "Please enter first number : $"
	msg2	DB 13, 10, "Please enter second number : $"
	msg3	DB 13, 10, "Press any key to continue...","$"
	n1	DW ?
	number	DB 5
		DB ?
		DB 5 DUP (?)	
.CODE
.STARTUP
	MOV	AH, 9
	LEA	DX, msg1
	INT	21h
	CALL	get_number
	MOV	n1, BX
	MOV	AH, 9
	LEA	DX, msg2
	INT	21h
	CALL	get_number
	MOV	AX, n1
	ADD	AX, BX
	MOV	CX, 0
	MOV	BX, 10
	LEA	SI, number + 2
loop_1:
	MOV	DX, 0
	DIV	BX
	MOV	[SI], DL
	INC	SI
	INC	CX
	CMP	AX, 0
	JNE	loop_1
	MOV	AH, 2
loop_2:
	DEC	SI
	MOV	DL, [SI]
	ADD	DL, "0"
	INT	21H
	LOOP	loop_2	
	MOV	AH, 9
	LEA	DX, msg3
	INT	21h
	MOV	AH, 8
	INT	21h
	.EXIT
get_number:
	MOV	AH, 0Ah
	LEA	DX, number
	INT	21h
	MOV	BX, 0
	MOV	CL, number[1]
	CMP	CL, 0
	JZ	next_2
	MOV	AH, 2
	MOV	DL, 13
	INT	21h
	MOV	DL, 10
	INT	21h
	MOV	CH, 0
	LEA	SI, number[2]
	MOV	DI, 10
	MOV	BX, 0
loop_3:
	MOV	AL, [SI]
	CMP	AL, "0"
	JB	next_1
	CMP	AL, "9"
	JA	next_1
	SUB	AL, "0"
	MOV	AH, 0
	XCHG	AX, BX
	MUL	DI
	ADD	BX, AX
next_1:
	INC	SI
	LOOP	loop_3
next_2:
	RET
.STACK
END
 
آخرین ویرایش:

hassancd

Active Member
دوست گرامی نمیدونم چرا جواب نمیده
من روی emu8086 اجرا میکنم و اینجوری تبدیل کردم و فقط یک عدد می گیره و میپره بیرون
کد:
    ;-------------------------------------------------
stseg segment
    dw 16 dup(0)
  
stseg ends
;-------------------------------------------------
dtseg segment
   
    msg1 DB 13, 10, "Please enter first number : $"
 msg2 DB 13, 10, "Please enter second number : $"
 msg3 DB 13, 10, "Press any key to continue...","$"
 n1 DW ?
 number DB 5
 DB ?
 DB 5 DUP (?)
    
dtseg ends
;-------------------------------------------------
cdseg segment
    main proc far
        assume cs:cdseg , ds:dtseg , ss:stseg
        
        mov ax,dtseg
        mov ds,ax
        
        ;start code
   MOV AH, 9
 LEA DX, msg1
 INT 21h
 CALL get_number
 MOV n1, BX
 MOV AH, 9
 LEA DX, msg2
 INT 21h
 CALL get_number
 MOV AX, n1
 ADD AX, BX
 MOV CX, 0
 MOV BX, 10
 LEA SI, number + 2
loop_1:
 MOV DX, 0
 DIV BX
 MOV [SI], DL
 INC SI
 INC CX
 CMP AX, 0
 JNE loop_1
 MOV AH, 2
loop_2:
 DEC SI
 MOV DL, [SI]
 ADD DL, "0"
 INT 21H
 LOOP loop_2 
 MOV AH, 9
 LEA DX, msg3
 INT 21h
 MOV AH, 8
 INT 21h
 .EXIT
get_number:
 MOV AH, 0Ah
 LEA DX, number
 INT 21h
 MOV BX, 0
 MOV CL, number[1]
 CMP CL, 0
 JZ next_2
 MOV AH, 2
 MOV DL, 13
 INT 21h
 MOV DL, 10
 INT 21h
 MOV CH, 0
 LEA SI, number[2]
 MOV DI, 10
 MOV BX, 0
loop_3:
 MOV AL, [SI]
 CMP AL, "0"
 JB next_1
 CMP AL, "9"
 JA next_1
 SUB AL, "0"
 MOV AH, 0
 XCHG AX, BX
 MUL DI
 ADD BX, AX
next_1:
 INC SI
 LOOP loop_3
next_2:
 RET

 ; exit program

 
        ;end code
        
        mov ah,4cH
        int 21H
    main endp
cdseg ends
end main
 

the_king

مدیرکل انجمن
از یک کامپایلر درست و حسابی استفاده کنید، در ضمن حجم Stack رو خیلی کم گرفتید (32 بایت).
اون (dw 16 dup(0 را به مقداری در حدود (dw 1024 dup(0 تغییر دهید.

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

برای دریافت کامپایلر ها به تاپیک زیر مراجعه شود :

emulator 8086
 

پیوست ها

  • b.zip
    918 بایت · بازدیدها: 18

the_king

مدیرکل انجمن
1-دستورleaچیکار می کنه
2-XCHG چیکار میکنه
ممنون

LEA آدرس یک موقعیت از حافظه را در یک رجیستر مورد نظر ذخیره می کنه، مثلا کد زیر را در نظر بگیرید :
کد:
number	DW 1234
.
.
.
LEA	BX, number
MOV	AX, 5678
MOV	[BX], AX
در سطر اول یک داده با نام number و مقدار 1234 تعریف شده. فرض کنیم که موقع اجرا این داده در آدرس x
از حافظه قرار بگیره. با اجرا شدن دستور LEA BX, number اون آدرس x در BX ذخیره میشه، یعنی BX تبدیل به
یک اشاره گر میشه که به number اشاره می کنه. پس اکنون [BX] معادل number خواهد بود.
به همین جهت با اجرا کردن دستور MOV [BX], AX مقدار AX یعنی عدد 5678 در number ذخیره میشه.

XCHG برای تعویض کردن مقدار دو داده با هم بکار می رود، مثلا XCHG AX, BX مقدار AX را در BX و مقدار BX را در AX
ذخیره می کند و در واقع جای آندو مقدار عوض می شود.
 

hassancd

Active Member
سوالی دیگر

ببخشید من زیاد مزاحم میشم
در قسمت get numbe و جاهایی دیگر این کد هارو داریم کارشون چی هستش


[MOV CL, number[1
یا
[LEA SI, number[2

lea رو فهمیدم این عدد 1 و 2 رو نمی فهمم برای چی هستش


بازم از شما تشکر می کنم
 

the_king

مدیرکل انجمن
ببخشید من زیاد مزاحم میشم
در قسمت get numbe و جاهایی دیگر این کد هارو داریم کارشون چی هستش


[MOV CL, number[1
یا
[LEA SI, number[2

lea رو فهمیدم این عدد 1 و 2 رو نمی فهمم برای چی هستش


بازم از شما تشکر می کنم

حافظه در اسمبلی همیشه حالت یک آرایه تک بعدی داره که اندیس هاش از 0 شروع می شوند.
مثلا کد زیر را در نظر بگیرید :
کد:
ch1	DB "Y"
msg	DB "TEST"
در کد بالا عبارت چهار بایتی TEST به عنوان یک رشته با نام msg تعریف شده. حالا میشه این msg را بصورت یک
آرایه در نظر گرفت. به این صورت که در [msg[0 کاراکتر T ذخیره شده و در [msg[1 کاراکتر E ذخیره شده و ...
فرضا با اجرا کردن کد زیر کاراکتر S در DL قرار می گیرد :
کد:
MOV	DL, msg[2]
توجه داشته باشید که اسمبلی شما را به محدوده اندیس مشخصی محدود نمی کند، مثلا [msg[-1 یک کاراکتر قبل
از شروع msg را مشخص می کند که در مثال بالا کاراکتر Y خواهد بود.

یک مثال دیگر :
کد:
ali	DB "A"
saeid	DB "SU"
king	DB 3 DUP (?)
number	DB 123
msg	DB "XYZ"
این داده ها بصورت یک رشته از بایت ها پشت سر هم در حافظه قرار می گیرند :
کد:
A, S, U, ?, ?, ?, 123, X, Y, Z

[ali[0 همان کاراکتر A است، [saeid[-1 هم همینطور. توجه داشته باشید که ali درست یک بایت قبل از saeid
تعریف شده. [king[-3 هم همان کاراکتر A است، چون سه بایت قبل از شروع king کاراکتر A ذخیره شده.

[number[1 کاراکتر X است. [saeid[6 هم همینطور. [0]msg هم همینطور.

[msg[-5 کاراکتر U است. [number[-4 هم همینطور. [saeid[1 هم همینطور.

حالا به سوال شما برگردیم، ساختار تعریف شده برای number را در نظر بگیرید :
کد:
 number DB 5
 DB ?
 DB 5 DUP (?)
خود number فقط یک بایت است که عدد 5 در آن ذخیره شده و مشخص می کند که رشته ای که از کاربر
دریافت می گردد حداکثر 5 کاراکتری خواهد بود.
بایت بعدی نامعلوم (؟) است و در هنگام دریافت رشته از کاربر طول رشته در آن ذخیره می گردد.
5 بایت هم بعد از قرار دارند که قرار است بعد از دریافت رشته از کاربر در آن ذخیره شود.

همانطور که قبلا اشاره کردم اندیس ها از 0 شروع می شوند، پس [number[0 همان عدد 5 است که
number ذخیره کرده.
[number[1 هم بایت ای است که بعد از آن قرار دارد، یعنی همان بایت نامعلوم (؟) که در هنگام
اجرا شدن برنامه طول رشته را مشخص می کند. به همین جهت بعد از اجرا شدن برنامه [MOV CL, number[1 طول
رشته را از [number[1 خوانده و در CL قرار می دهد.
[number[2 هم یک بایت بعد از آن است، یعنی اولین کاراکتر آن رشته 5 کاراکتری (?) DB 5 DUP
به همین دلیل [LEA SI, number[2 آدرس اولین کاراکتر رشته را در SI قرار می دهد.
 

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

بالا