إخراج القيم المتغيرة في x86 ASM
سؤال
أنا أكتب برنامجًا في التجميع ولا يعمل ، لذلك أود إخراج متغيرات في وظائف x86 لضمان أن القيم هي ما أتوقع أن تكون عليه. هل هناك طريقة بسيطة للقيام بذلك ، أم أنها معقدة للغاية؟
إذا جعل الأمر أكثر بساطة ، يتم استخدام وظائف التجميع من وظائف C ويتم تجميعها باستخدام GCC.
المحلول
يبدو أن سؤالك هو على غرار "كيف يمكنني طباعة القيم المتغيرة في مجمع x86". لا يعرف X86 نفسه كيفية القيام بذلك ، لأنه يعتمد تمامًا على جهاز الإخراج الذي تستخدمه (وتفاصيل الواجهة المقدمة من نظام التشغيل لجهاز الإخراج).
تتمثل إحدى طرق القيام بذلك في استخدام نظام التشغيل ، كما ذكرت نفسك في إجابة أخرى. إذا كنت على X86 Linux ، فيمكنك استخدام sys_write
SYS Call لكتابة سلسلة إلى الإخراج القياسي ، مثل هذا (بناء جملة GNU):
STR:
.string "message from assembler\n"
.globl asmfunc
.type asmfunc, @function
asmfunc:
movl $4, %eax # sys_write
movl $1, %ebx # stdout
leal STR, %ecx #
movl $23, %edx # length
int $0x80 # syscall
ret
ومع ذلك ، إذا كنت ترغب في طباعة القيم الرقمية ، فإن الطريقة الأكثر مرونة هي استخدام printf()
وظيفة من مكتبة C القياسية (تذكر أنك تتصل بمجموعك من C ، لذلك من المحتمل أنك تربط المكتبة القياسية على أي حال). هذا مثال:
int_format:
.string "%d\n"
.globl asmfunc2
.type asmfunc2, @function
asmfunc2:
movl $123456, %eax
# print content of %eax as decimal integer
pusha # save all registers
pushl %eax
pushl $int_format
call printf
add $8, %esp # remove arguments from stack
popa # restore saved registers
ret
شيئين يجب ملاحظة:
- تحتاج إلى حفظ واستعادة السجلات ، لأنها تتعرض للمكالمة ؛ و
- عند استدعاء وظيفة ، يتم دفع الوسائط بترتيب يمين إلى اليسار.