آزمایشگاه زبان اسمبلی 64 بیت 3 قسمت 3

هییی!! از شکیبایی شما سپاسگزارم، واقعاً از آن قدردانی می کنم. اگر تا به حال آخرین وبلاگ من را نخوانده اید، اکنون آن را بخوانید! بنابراین شما یک زمینه را دریافت می کنید.
اجازه دهید قبل از اینکه توسط خوانندگانم به خاطر تعلیق نگه داشتن راهنما مورد ضرب و شتم قرار بگیرم، شروع کنیم.
برای برنامه حلقه در معماری aarch64 قدم بزنید
1. بخش داده (.data):
.data
msg: .ascii "Loop: #\n"
len= . - msg
- msg یک رشته “حلقه: #\n” است، که در آن # یک مکان نگهدار برای شمارنده حلقه است.
- len طول رشته msg است که به عنوان تفاوت بین آدرس فعلی و آدرس پیام محاسبه می شود.
2. بخش متن (text):
.text
.globl _start
min = 0
max = 30
_start:
mov x19, min
- .globl _start: _start را به عنوان نماد جهانی (نقطه ورودی) اعلام می کند.
- min = 0 و max = 30: ثابت برای کران حلقه.
- _start:: برچسبی که نقطه ورود برنامه را مشخص می کند.
- mov x19, min: x19 (شاخص حلقه) را به 0 مقداردهی می کند.
3. آماده سازی حلقه و پیام:
loop:
add x15, x19, 0x30
adr x14, msg+6
mov x12, 10
udiv x13, x19, x12
add x16, x13, 0x30
cmp x16, 0x30
b.eq ones
strb w16, [x14]
- اضافه کردن x15, x19, 0x30: تبدیل حلقه شاخص (x19) به کاراکتر ASCII.
- adr x14, msg+6: آدرس مکان نگهدار # در رشته پیام.
- mov x12, 10: برای تقسیم 10 را به x12 منتقل کنید.
- udiv x13, x19, x12: تقسیم x19 بر 10، ضریب در x13.
- x16, x13, 0x30 اضافه کنید: ضریب را به ASCII تبدیل کنید.
- cmp x16, 0x30: اگر ضریب 0 باشد، مقایسه کنید.
- b.eq ones: اگر ضریب 0 باشد، به یکها انشعاب دهید.
- strb w16، [x14]: کاراکتر ضریب را ذخیره کنید.
4. Handling Ones مکان:
ones:
adr x14, msg+7
msub x13, x13, x12, x19
add x13, x13, 0x30
strb w13, [x14]
- adr x14, msg+7: آدرس کاراکتر بعدی بعد از مکان نگهدار #.
- msub x13, x13, x12, x19: باقیمانده را محاسبه کنید.
- x13, x13, 0x30 اضافه کنید: باقیمانده را به ASCII تبدیل کنید.
- strb w13، [x14]: کاراکتر باقیمانده را ذخیره کنید.
- چاپ پیام:
mov X0, 1
adr x1, msg
mov x2, len
mov x8, 64
svc 0
- mov X0, 1: تنظیم کننده فایل stdout.
- adr x1, msg: آدرس رشته پیام.
- mov x2, len: طول رشته پیام.
- mov x8, 64: شماره Syscall برای نوشتن.
- svc 0: syscall را بسازید.
6. حلقه افزایش و بررسی:
add x19, x19, 1
cmp x19, max
b.ne loop
mov x0, 0
mov x8, 93
svc 0
- اضافه کردن x19، x19، 1: شاخص حلقه افزایشی.
- cmp x19, max: شاخص حلقه را با حداکثر مقایسه کنید.
- حلقه b.ne: اگر شاخص حلقه برابر با حداکثر نیست، حلقه را تکرار کنید.
- mov x0, 0: خروج از کد وضعیت.
- mov x8, 93: شماره Syscall برای خروج.
- svc 0: Syscall را برای خاتمه برنامه ایجاد کنید.
به طور کلی این برنامه از دقیقه (0) تا حداکثر (30) تکرار می شود، شاخص حلقه را به یک رشته تبدیل می کند و آن را با استفاده از syscall چاپ می کند. این برنامه تبدیل اعداد به نمایش ASCII آنها را انجام می دهد و از تماس های سیستمی برای چاپ پیام و در نهایت خروج از برنامه استفاده می کند. هر تکرار “Loop: #\n” را چاپ می کند که در آن # شاخص حلقه فعلی است.
این را می توان در معماری x86_64 نیز نوشت. کد به شرح زیر است.
.text
.globl _start
min = 0 /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
max = 33
_start:
mov $min,%r15 /* loop index */
loop:
mov $0,%rdx
mov %r15,%rax
mov $10,%r12
div %r12
mov %rax,%r14
add $'0',%r14
cmp $'1',%r14
je loopOnes
mov %r14b,msg+6
loopOnes:
mov %rdx,%r14
add $'0',%r14
mov %r14b,msg+7
movq $len,%rdx
movq $msg,%rsi
movq $1,%rdi
movq $1,%rax
syscall
/* ... body of the loop ... do something useful here ... */
inc %r15 /* increment index */
cmp $max,%r15 /* see if we're done */
jne loop /* loop if we're not */
mov $0,%rdi /* exit status */
mov $60,%rax /* syscall sys_exit */
syscall
.section .data
msg: .ascii "Loop: #\n"
len = . - msg
خروجی [I almost forgot]
خروجی هر دو معماری به این صورت است
بنابراین این قسمت سوم وبلاگ است، اما من شماره سه را دوست ندارم. بنابراین، من هیجان زده هستم که یک قسمت دیگر را به وبلاگ خود اضافه کنم، گیلاس در بالا برای تکمیل مجموعه! و همچنین شامل چند آزمایش بیشتر روی اسمبلر.
ممنون که خواندید!
تا اون موقع کدنویسی مبارک!!👋