برنامه نویسی

آزمایشگاه زبان اسمبلی 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]: کاراکتر باقیمانده را ذخیره کنید.
  1. چاپ پیام:
     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]

خروجی هر دو معماری به این صورت است

توضیحات تصویر

بنابراین این قسمت سوم وبلاگ است، اما من شماره سه را دوست ندارم. بنابراین، من هیجان زده هستم که یک قسمت دیگر را به وبلاگ خود اضافه کنم، گیلاس در بالا برای تکمیل مجموعه! و همچنین شامل چند آزمایش بیشتر روی اسمبلر.
ممنون که خواندید!

تا اون موقع کدنویسی مبارک!!👋

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا