الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

برنامج لنقل البيانات ومن ثم جمعها

بدأه حار فكري في 5 ديسمبر 2012 · 12 رد · 999 مشاهدة · في لغة Assembly لأنظمة 16, 32, 64 بت
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله وبركاته

بسم الله الرحمن الرحيم

لدي سؤال في لغة الاسمبلي اذا يستطيعاحد ان يجاوبي

يوجد لدينا

هذه الارقام

27345, 28521,29533,30105,32375

في ال offset رقم 10

نريد نقلها الى ال offset رقم 30

ومن ثم جمعها

model small.

stack 64 .

data .

count equ 5

DD 28521,29533,30105,32375,27345

org 0010h

?DD

CODE.

proc far

mov ax , @data

mo ds,ax

mov si,offset

mov di , offset

mov cx, 0010

mov ax, [si]__>data

mov [di] , ax

inc si

inc di

dec cx

jnz

mov dx , count

mov si , 00

mov si , offset

mov ax , 00

mov bx , ax

add ax , [si]__>data

adc bx , 00

inc si

inc si

dec dx

jnz

mov sum , ax

mov sum +2 , bx

mov ah , 4ch

iint 21h

end p

end main

انا لا افهم في لغة الاسمبلي الكثير سوى ال mov and pop and posh

شرحهم الدكتور وبدا يعطينا كتابة البرامج وكل يوم يعطينا امر جديد يختلف عن البرنامج السابق لا اعرف ما الحل

وهذا البرنامج اعرف يوجد فيه الكثير من الاخطاء وارجو مساعدتي في تصحيحها الجزء الاول من الحل النقل كان يوجد لدي برنامج وعملت على نفس النمط ولم اعرف كيف اكمل البرنامج بجمع الاعداد لا اعرف هل هو صحيح ام لا ؟

ارجو المساعدة

#2

وايضا توضيح امر org لماذا نستخدمه ؟

#3

مساء الخير

اي حد ممكن يساعدني ارجوكم اريد الحل ضروري

#4
حار فكري كتب:

وايضا توضيح امر org لماذا نستخدمه ؟

لتعريف العنوان الذي سيكون فيها البداية لتخزين البرنامج فى الذاكرة وله صيغة عامة

<label>org<value>

مثال

Start org 0×00

لدي طلب منك حاولي فى السؤال الاصلي تحديد المطلوب جيدا واعادة كتابة الكود بشكل منظم لانني لم افهم شئ مما تريدينه بالظبط

2

GoodBye

#5

انا اكتب مجرد

org 10

فقط ناخذ هكذا

oxoo لا اعلمها

#6
 model small.
stack 64 .
data .
count equ 5
DD 28521,29533,30105,32375,27345
org 0010h
?DD
CODE.
proc far
mov ax , @data
mo ds,ax
mov si,offset
mov di , offset
mov cx, 0010
mov ax, [si]__>data
mov [di] , ax
inc si
inc di
dec cx
jnz
mov dx , count
mov si , 00
mov si , offset
mov ax , 00
mov bx , ax
add ax , [si]__>data
adc bx , 00
inc si
inc si
dec dx
jnz
mov sum , ax
mov sum +2 , bx
mov ah , 4ch
iint 21h
end p
end main
#7

لو سمحتو اي حد يساعدني

لا احد يفهم لغة الاسمبلي ؟؟ ام سؤالي غير مفهوم ؟؟ ارجوكم

#8
.model small
.stack 64
.data
org 10		; offset 10 from beginning of data segment
src dw 27345,28521,29533,30105,32375

org 30		; offset 30 from beginning of data segment
dst dw 0,0,0,0,0

count equ 5

.CODE
main:
xacker proc near
mov ax , @data
mov ds,ax

push ds		; we need ES to equal DS because movsx works on DS:SI, ES:DI
pop es		;

mov si, offset src
mov di, offset dst
mov cx, count
rep movsw	; copy CX words from DS:SI -> ES:DI <== this copies 5 words from offset 10 to offset 30

mov ah , 4ch
int 21h
xacker endp
end main

بالنسبة لجمع الأعداد، عليك مراعاة أن ناتج الجمع سيكون قيمة أكبر من 0FFFFh (أي أكبر من استطاعة التخزين في مسجل 16 بت) والانتباه إلى الجمع مع الحمل

3

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#9

الله يجزيك كل خير على هذه المساعدة القيمة

لكن عندي بعض الاسئلة على الكود

1-استخدمت ال dw لكن كما اعرف لان الارقام كبيرة يجب استخدام ال dd

2- وهذا الامر ما فائدته وهل من الضروري كتابته( dst dw 0,0,0,0,0) ؟

3- عملية الـ pop and push لا يجوز استخدامها في Stack register لاني سبق وسالت الدكتور عن هذا الامر وقال لي يجوز استخدامه هنا ؟

4- ممكن توضح لي هذا الامر (rep movsw ) ؟

الرجاء الرد على الاسئلة اعرف اني ازعجتكم كثيرا :blush:

#10

وايضا استفسار انا اريد ان اعرف كيفية الجمع بين امرين النقل الى موقع اخر وعملية الجمع في نفس البرنامج النقل يتم ومن ثم الجمع مباشرة ؟؟؟

بالنسبة لجمع الأعداد، عليك مراعاة أن ناتج الجمع سيكون قيمة أكبر من 0FFFFh (أي أكبر من استطاعة التخزين في مسجل 16 بت) والانتباه إلى الجمع مع الحمل

وبالنسبة لملاحظتك هكذا كانت الارقام بالكتاب وتم جمعهم هكذا

http://im19.gulfup.com/c0tE1.png

تم تعديل هذه المشاركة بواسطة حار فكري في 8 ديسمبر 2012 في 20:00

#11
حار فكري كتب:

1-استخدمت ال dw لكن كما اعرف لان الارقام كبيرة يجب استخدام ال dd

الأرقام المذكورة في المثال ليست كبيرة، ويمكن تخزينها ضمن حجم word (2 بايت)

أيضاً افترضت أننا نتعامل مع برنامج 16 بت، بالتالي لا نملك مسجّلات بطول double word (4 بايت)

حار فكري كتب:

2- وهذا الامر ما فائدته وهل من الضروري كتابته( dst dw 0,0,0,0,0) ؟

هذه طريقة للحل

الطريقة الأخرى هي العنونة عن بداية ES بمقدار 30 والبدء بنقل البيانات إليه.

حار فكري كتب:

3- عملية الـ pop and push لا يجوز استخدامها في Stack register لاني سبق وسالت الدكتور عن هذا الامر وقال لي يجوز استخدامه هنا ؟

لم أسمع بهذا من قبل، ألم يذكر سبب ودليل على كلامه؟

يمكنك طبعاً التخلي عنها بنسخ قيمة ds أو ax باستخدام mov

حار فكري كتب:

4- ممكن توضح لي هذا الامر (rep movsw ) ؟

movs يقوم بنسخ بيانات من مسجل لآخر

الشكل movsw يسمح بنسخ word من DS:SI إلى ES:DI (لا تحتاج لتحديد المسجلات)

وتسمح التعليمة movs بأخذ سابقة (prefix) لها مثل rep والتي تقوم بتكرار تنفيذ التعليمة movs لعدد من المرات يساوي القيمة الموجودة في المسجل CX

في مثالنا وضعت القيمة 5

عند التنفيذ أول مرة يتم إنقاص CX وتصبح 4 ويكون قد تم نسخ word (أول رقم من المثال) إلى المكان الجديد

ثم يتم تكرار التنفيذ مرة أخرى فتصبح CX = 3

ثم مجدداً فمجدداً إلى أن تصبح القيمة CX = 0 عندها يتم الانتقال إلى التعليمة التالية.

حار فكري كتب:

وايضا استفسار انا اريد ان اعرف كيفية الجمع بين امرين النقل الى موقع اخر وعملية الجمع في نفس البرنامج النقل يتم ومن ثم الجمع مباشرة ؟؟؟

جملة وسؤال غير واضح إطلاقاً (الصياغة متداخلة فالسؤال أصبح غير مفهوم ولا حتى مقروء) :wacko:

3

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#12
حار فكري كتب:

وبالنسبة لملاحظتك هكذا كانت الارقام بالكتاب وتم جمعهم هكذا

http://im19.gulfup.com/c0tE1.png

هذه طريقة صحيحة بالطبع، من خلال استخدام التعليمة ADC (التي تراعي الحمل)

وللتوضيح عن استخدامها:

Syntax: adc dest, src
dest: memory or register
src:  memory, register, or immediate
Action: dest = dest + src + CF

فالسطر:

adc  bx, 0

تعني أنه عندما يتم تنفيذ add ويكون هناك حمل فإن قيمة CF ستكون مساوية لقيمة الحمل (عندما تجمع 8 مع 3 سيكون الناتج 1 والحمل 1 مثلاً)

وبالتالي فعندما تجمع الأرقام في المثال: 27345+28521 = 55866

ثم تأتي لجمع 29533 معه فيكون الناتج 85399 وهذا يساوي 14D97h وهي أكبر من استطاعة تخزين word وبالتالي تصبح الـ CF = 1 أما القيمة في AX فتكون بدون حمل وتساوي 4D97h

ثم تأتي لجمع 30105 معه

فيكون الناتج 49968 وهذه تساوي C330h بدون حمل، فيتم تصفير CF ويتم (من خلال ADC) جمع 0 إلى قيمة BX التي فيها الحمل السابق (والمساوي 1) فتبقى BX = 1

ثم أخيراً سنضيف إليه 32375 والنتيجة ستكون 82343 وهذه تساوي 141A7h فالجزء باللون الأزرق يخزن في AX والذي باللون الأحمر يخزن في CF

ثم تأتي ADC لتصبح القيمة في BX=BX+0+CF أي BX=1+0+1=2

لكن كيف سنقوم بتخزين الرقم بشكله النهائي الآن؟ لاحظي السطرين

mov sum, ax
mov sum+2, bx

في البداية نضع القيمة 41A7h في SUM

ثم نضع ناتج الحمل الموجود في المسجل BX في SUM+2 (طبعاً +2 حتى نتجاوز أول بايتين المخزن فيهما القيمة 41A7h بالإضافة إلى أن التخزين في الذاكرة يتم بصيغة little-endian .. الرقم يخزن بشكل معكوس لهذا يكون الحمل إلى أقصى اليمين بعكس ما تسجله على ورقة في دفترك)

وتكون القيمة المخزنة عند الإزاحة SUM بالشكل:

A7410200

وهي بالشكل little-endian كما ذكرت وتقرأ: 000241A7h

وهي ناتج الجمع.

3

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#13

شكرا جزيلا اخي على هذا الجهد الرائع :thumb_up: :clapping: :clapping:

لقد افدتني كثيرا لكن هناك فرق بيننا بالمستوى ربما تشرح بمستوى اعلى , وانا فقط على اعرف سوء ابسط الامور

مواضيع مشابهة