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

حلقة تكرار تفشل في الإستمرار ؟

بدأه Mr.B في 15 يناير 2011 · 5 رد · 1,176 مشاهدة · في أرشيف قسم الـــ Assembly
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

بدأت أمس\قبل أمس بتعلم الأسمبلي .. قرأت هنا وهناك حتى وجدت موضع قدم . كتبت عدد من الأكواد البسيطة. وهذا آخر ماوصلت له

حاولت أعمل حلقة تكرار loop ودائما تفشل ( أعلم أن هناك if و while في masm ولكنني إريد أن أتعلم الأسمبلي الكلاسيكسة ) :

.486
.model flat, stdcall
option casemap :none

include		\masm32\include\kernel32.inc
include		\masm32\include\user32.inc
include		\masm32\include\masm32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\masm32.lib

	.data

		text db "Hi, this is a loop!",13,10,0

	.code

		start:

			xor eax,eax

				loopprint:
						push offset text
						call StdOut
						inc eax
				end loopprint

			call loopprint
			cmp eax,10
			jnz loopprint
			push offset text
			call StdOut
			push 0
			call ExitProcess

		end start

قام بعملية الطباعة مرّة واحدة فقط .. في المحاولة الثانية :

.486
.model flat, stdcall
option casemap :none


include		\masm32\include\kernel32.inc
include		\masm32\include\user32.inc
include		\masm32\include\masm32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\masm32.lib

	.data

		text db "Hi, this is a loop!",13,10,0

	.code

		start:

			xor eax,eax
			push eax
			call code1
				code1:
					push offset text
					call StdOut
					pop eax
					inc eax
					push eax
					call code2

				end code1

				code2:

					pop eax
					cmp eax, 10
					jnz code1

				end code2


			push 0
			call ExitProcess




		end start

ظهر لي خطأ :

loop.asm(34) : error A2006: undefined symbol : code2

حاولت تجاوزة بهذا الكود :

.486
.model flat, stdcall
option casemap :none


include		\masm32\include\kernel32.inc
include		\masm32\include\user32.inc
include		\masm32\include\masm32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\masm32.lib

	.data

		text db "Hi, this is a loop!",13,10,0

	.code

		start:

			xor eax,eax
			push eax
			call code1
				code1:
					push offset text
					call StdOut
					pop eax
					inc eax
					push eax
					xor ebx,ebx
					mov ebx, offset code2
					call ebx

				end code1

				code2:

					pop eax
					cmp eax, 10
					jnz code1

				end code2


			push 0
			call ExitProcess




		end start

ولم أفلح ,, وطبعا بدأت تتتحول المحاولات للنوع الغبي :lol: , ما المشكلة فيه ؟

وسؤال آخر .. كيف أنقل قيمة إلى عنوان في الذاكرة ؟ محاولتي قمت بإنشاء متغير :

adder db ?

وحاولت أن أنقله له قيمه هكذا :

mov offset adder, "ABCD"

و

mov offset adder, 1

ولكن يبدو أنني إرتكبت خطأ فظيع :blush::P

تم تعديل هذه المشاركة بواسطة Mr.B في 15 يناير 2011 في 04:22

#2

مرحباً بك،

جرب هذا

                start:
		xor eax,eax
@@:
		cmp eax,10
		je @F
			push offset text
			call StdOut
			inc eax
		jmp @B
@@:
		push 0
		call ExitProcess
                end start

الأمر بسيط، يمكنك تنفيذ loop بطريقتين عامتين كالتالي:

xor	eax,eax
_loop:
cmp	eax,10
je	end_loop
; do stuff here
inc	eax
jmp	_loop

;------------------------------------------------

mov	ecx,10	; ECX = counter
_loop:
; do stuff here
loop	_loop	; decrease CX by 1 then check if CX = 0 to exit, otherwise execute the loop again

بالنسبة للسؤال الثاني:

adder db ?

mov offset adder, "ABCD"	; WRONG, you dont need offset here
mov addr, "ABCD"		; WRONG, addr is one byte, "ABCD" is 4 bytes, you might overwrite something important!

mov addr, "A"		; CORRECT

addr db 4 dup (?)		; reserve 4 uninitialized bytes or reserve a DD which is 4 bytes long

mov addr, "ABCD"		; CORRECT

Do as I say, not as I do

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

#3

أشكرك أخي Xacker على التوضيح , لكن واجهت مشكلة بكل الأكواد .. يبدو أنها لم تنجح ..

في الكود الأول ,, ( حقيقة لم أفهم معنى الرموز به @ و @F و @B , فشكلها غريب ) إلا أنني نستخه وألصقته ..

ثم طبع لي مرّة واحدة فقط !

الثاني , طبّقته .. ولكن ظهرت مشكله , ثم عدّلته هكذا :

		start:

			xor     eax,eax
			_loop:
			cmp     eax,10
			je      end_loop

			push offset text
			call StdOut

			inc     eax
			jmp     _loop

			end_loop:
				push 0
				call ExitProcess

		end start

إشتغل .. ولكنه أيضاّ طبع لي مرّه واحده فقط ! , لا أفهم مالسبب ؟

سؤال بسيط ماذا يسمى الجزء " _loop " هل هو دالّة ؟ وكيف يتم تنفيذه ؟

يعني لو لم يستدعى , هل سيتهم تجاهله مثل الدوال ؟

text db 4 dup (?)

لم تنفع هذه الطريقة بنقل أكثر من بايت (حرف) للعنوان : (

حقيقة أنا الا أعتمد على مصدر محدد .. بل على كتيب عن الأسمبلي 16 بت وبعض كتب الهندسة العكسية

لأن كل الكتب الأسمبلي 32 بت التي عندي تستخدم أمثلتها تستخدم واجهات مرئية GUI لذا لا أتبّعها فلا أفكر بتعلم برمجة الواجهات بالأسمبلي

و المشكله الثانية أنها تستخدم ميزات MASM التي تبعده عن شكل الأسمبلي .. لذا أواجهه هذه المشاكل

تم تعديل هذه المشاركة بواسطة Mr.B في 15 يناير 2011 في 22:39

#4

بالنسبة لـ

B@

F@

@@

راجع آخر مشاركة لي في الموضوع:

/index.php?showtopic=235116

أما _loop فهذه تشير إلى لافتة (label) حتى يتم الانتقال إليها بالعبارة

jmp _loop

كما حاولت *تقريباً مع خطأ* أن تفعل في أول كود تجربة لك وضعته في هذا الموضوع بالعبارة loopprint

بالنسبة للكود، لنفرض أنه التالي:

.486
.model flat,stdcall
option casemap:none

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\masm32.inc
includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\masm32.lib


.data
text db 'Hi, this is a loop!',13,10,0

.code

start:
    xor ebx,ebx
@@:
    cmp ebx,10
    je @F
    push offset text
    call StdOut
    inc ebx
    jmp @B
@@:
    push 0
    call ExitProcess
end start

لاحظ أني قمت بتغيير المسجل من EAX إلى EBX حيث أن التابع StdOut يقوم بتغيير قيمتها ولا يحافظ عليها بالتالي سيفشل تنفيذ التكرار لـ 10 مرات وقد يصبح لآلاف المرات..

أما EBX فقيمتها لن تتغير قبل وبعد تنفيذ StdOut فيمكن استخدامها بأمان كعداد للحلقة.

احفظ الملف بالاسم test.asm ومن ثم قم بنسخ التالي:

@echo off

if not exist rsrc.rc goto over1
\masm32\bin\rc /v rsrc.rc
\masm32\bin\cvtres /machine:ix86 rsrc.res
 :over1

if exist "test.obj" del "test.obj"
if exist "test.exe" del "test.exe"

\masm32\bin\ml /c /coff "test.asm"
if errorlevel 1 goto errasm

if not exist rsrc.obj goto nores

\masm32\bin\Link /SUBSYSTEM:CONSOLE "test.obj" rsrc.res
 if errorlevel 1 goto errlink

dir "test.*"
goto TheEnd

:nores
 \masm32\bin\Link /SUBSYSTEM:CONSOLE "test.obj"
 if errorlevel 1 goto errlink
dir "test.*"
goto TheEnd

:errlink
 echo _
echo Link error
goto TheEnd

:errasm
 echo _
echo Assembly Error
goto TheEnd

:TheEnd

pause

إلى ملف بالاسم makeit.bat في ذات المجلد، الملف يحوي التعليمات اللازمة لتنفيذ عمليتي Assemble & Link لتطبيق الكونسول الذي تقوم بكتابته.

يكفي أن تقوم بتنفيذه بعد الانتهاء ليقوم بإنشاء ملف obj ومن ثم الملف التنفيذي.

قمت بتنفيذ البرنامج وستحصل على التالي ما لم تخطئ بإحدى الخطوات السابقة الذكر:

C:\masm32\src>C:\masm32\src\test.exe
Hi, this is a loop!
Hi, this is a loop!
Hi, this is a loop!
Hi, this is a loop!
Hi, this is a loop!
Hi, this is a loop!
Hi, this is a loop!
Hi, this is a loop!
Hi, this is a loop!
Hi, this is a loop!
1

Do as I say, not as I do

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

#5

أخيراً بالنسبة لنقل البايتات:

.data
text db 4 dup (0)

.data?
text2 db 4 dup (?)

.code

start:
    mov dword ptr [text], "ABCD"
    mov  dword ptr [text2], "ABCD"

انتبهت إلى أني كتبت لك addr كاسم للمتحول وهذا خطأ مني لأن addr كلمة محجوزة.

التعديل في الكود في الأعلى.

Do as I say, not as I do

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

#6

أشكرك جزيل الشكر أخي Xacker ,,

الحمد لله كل نجحت جميع الأكواد ! :)

C:\>type loop.asm
.486
.model flat, stdcall
option casemap :none
include         \masm32\include\kernel32.inc
include         \masm32\include\user32.inc
include         \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\masm32.lib
        .data
                text db "This is a loop",13,10,0
        .code
                start:
                        xor ebx,ebx
                        _loop:
                                push offset text
                                call StdOut
                                inc ebx
                        cmp ebx,10
                        jnz _loop
                        push 0
                        call ExitProcess
                end start
C:\>\masm32\bin\ml /c /Zd /coff loop.asm
Microsoft ® Macro Assembler Version 6.14.8444
Copyright © Microsoft Corp 1981-1997.  All rights reserved.
 Assembling: loop.asm
C:\>\masm32\bin\Link /subsystem:console loop.obj
Microsoft ® Incremental Linker Version 5.12.8078
Copyright © Microsoft Corp 1992-1998. All rights reserved.
C:\>loop.exe
This is a loop
This is a loop
This is a loop
This is a loop
This is a loop
This is a loop
This is a loop
This is a loop
This is a loop
This is a loop
C:\>echo =========================================================
=========================================================
C:\>type cpmem.asm
.486
.model flat, stdcall
option casemap :none
include         \masm32\include\kernel32.inc
include         \masm32\include\user32.inc
include         \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\masm32.lib
        .data
        .data?
                text db 4 dup (?)
        .code
                start:
                        mov dword ptr [text], "DCBA"
                        push offset text
                        call StdOut
                        push 0
                        call ExitProcess
                end start
C:\>\masm32\bin\ml /c /Zd /coff cpmem.asm
Microsoft ® Macro Assembler Version 6.14.8444
Copyright © Microsoft Corp 1981-1997.  All rights reserved.
 Assembling: cpmem.asm
C:\>\masm32\bin\Link /subsystem:console cpmem.obj
Microsoft ® Incremental Linker Version 5.12.8078
Copyright © Microsoft Corp 1992-1998. All rights reserved.
C:\>cpmem.exe
ABCD
C:\>echo Done! =)
Done! =)
C:\>

أشكرك أخي العزيز , بارك الله فيك .. مقدر لك المساعدة :blush:

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