XA(1) General Commands Manual XA(1)

xa - کراس‌اسمبلر 6502/R65C02/65816

xa [OPTION]... FILE

xa یک کراس‌اسمبلر چندگذر (multi-pass) برای پردازنده‌های ۸ بیتی از سری 6502 (مانند 6502، 65C02، 6504، 6507، 6510، 7501، 8500، 8501 و 8502)، Rockwell R65C02، و پردازندهٔ ۱۶ بیتی 65816 است. برای توضیحات مربوط به نحو، بخش ASSEMBLER SYNTAX را در ادامهٔ این صفحهٔ راهنما ببینید.

پس از ۲۰ خطا متوقف نشو، بلکه تمام خطاها را نمایش بده.
خروجی پرجزئیات (verbose).
کدهای دستوری (opcodes) مربوط به CMOS غیرفعال شود (حالت پیش‌فرض اجازه دادن به کدهای دستوری R65C02 است).
کدهای دستوری 65816 غیرفعال شود (پیش‌فرض).
کدهای دستوری 65816 مجاز باشند.
خطوط باز/بسته شدن بلوک نمایش داده شوند (بخش PSEUDO-OPS را ببینید).
تولید فایل‌های شیء o65 به‌جای فایل‌های اجرایی (هیچ پیوندزدنی انجام نمی‌شود)؛ ممکن است فایل‌ها حاوی ارجاعات تعریف‌نشده باشند.
تنظیم نام فایل خروجی. پیش‌فرض a.o65 است؛ از نام فایل ویژهٔ - برای فرستادن خروجی به خروجی استاندارد استفاده کنید.
تنظیم نام فایل فهرست‌بندی (listing). پیش‌فرض هیچ است؛ از نام فایل ویژهٔ - برای چاپ فهرست‌بندی در خروجی استاندارد استفاده کنید.
تنظیم قالب فهرست‌بندی؛ پیش‌فرض plain است. تنها قالب دیگری که در حال حاضر پشتیبانی می‌شود html است.
تنظیم نام فایل گزارش خطا (errorlog)؛ پیش‌فرض هیچ است.
تنظیم نام فایل فهرست برچسب‌ها (labellist)؛ پیش‌فرض هیچ است. این همان جدول نمادها است و می‌تواند توسط دیزاسمبلرهایی مانند dxa(1) برای بازسازی کد مبدأ استفاده شود.
افزودن فهرست ارجاع متقابل (cross-reference) به فهرست برچسب‌ها (نیازمند -l است).
تنظیمات سازگاری را برای سازگاری بیشتر (نه کامل!) با سایر اسمبلرها و پایگاه‌های کد 6502 فعال می‌کند. مجموعه‌های سازگاری پشتیبانی‌شده در حال حاضر عبارتند از MASM، CA65 و C، به همراه XA23 که به‌عنوان گزینه‌ای منسوخ‌شده برای پایگاه‌های کدی که به سازگاری با نسخهٔ قبلی xa وابسته‌اند در دسترس است. می‌توان چندین مجموعهٔ سازگاری را مشخص و با یکدیگر ترکیب کرد؛ مانند: -XMASM -XXA23.
-XMASM اجازه می‌دهد برای سازگاری با MASM، دو‌نقطه در کامنت‌ها ظاهر شود. این امر بر تفسیر دو‌نقطه در جاهای دیگر تأثیر نمی‌گذارد و ممکن است در نسخه‌های بعدی به حالت پیش‌فرض تبدیل شود.
-XCA65 قابلیت‌های نحوی سازگارتری با ca65(1) اضافه می‌کند. این گزینه امکان استفاده از := را برای تعریف برچسب‌ها (به‌جای = ساده) فراهم می‌کند، و پشتیبانی از برچسب‌های بی‌نام و برچسب‌های محلی «ارزان» با استفاده از نویسهٔ @ را اضافه می‌کند، اما کاربرد دیگر آن را برای حالت ۲۴ بیتی غیرفعال می‌سازد (بخش ASSEMBLER SYNTAX را ببینید).
-XC امکان استفاده از شیوه‌های کدگذاری عددی به سبک C مانند 0xHEX و 0OCTAL را فعال می‌کند.
-XXA23 سازگاری جزئی با xa نسخهٔ 2.3.x را بازمی‌گرداند. به‌ویژه، از ^ برای تولید نویسه‌های کنترلی استفاده می‌کند، نویسه‌های گریز (escaped characters) با \ را غیرفعال می‌سازد، کامنت‌های چندخطی تودرتو را مجاز می‌کند و تمام ماکروهای پیش‌پردازندهٔ ازپیش‌تعریف‌شدهٔ xa را غیرفعال می‌نماید. گرچه بخش‌هایی از این گزینه همچنان نحو پشتیبانی‌شده باقی می‌مانند، اما خود این گزینه ذاتاً منسوخ شده است و ممکن است در انتشار بعدی 2.x یا 3.x حذف شود.
پشتیبانی از برچسب‌های بی‌نام با استفاده از دو‌نقطه به سبک ca65(1)، اما بدون باقی قابلیت‌های پشتیبانی‌شدهٔ ca65(1). برای نمونه، این امر اجازه می‌دهد از آن‌ها در حالت 65816 استفاده شود. این گزینه مستلزم -XMASM است.
این گزینه منسوخ شده است و در نسخه‌های آینده حذف خواهد شد؛ به‌جای آن از -XMASM استفاده کنید. این گزینه اجازه می‌دهد برای سازگاری با MASM، دو‌نقطه در کامنت‌ها ظاهر شود. این امر بر تفسیر دو‌نقطه در جاهای دیگر تأثیر نمی‌گذارد و ممکن است در نسخه‌های آینده به پیش‌فرض تبدیل شود.
به نویسهٔ هشتک (^) اجازه می‌دهد یک نویسه را با $1f/31 ماسک کند. این قابلیت می‌تواند به‌عنوان میانبری برای نویسه‌های کنترلی استفاده شود، مانند ^m^j که به یک بازگشت به ابتدای سطر (carriage return) به همراه سطر جدید (linefeed) تبدیل می‌شود.
اجرای اسمبلر در حالت بازنشانی (relocating mode)، یعنی استفاده از قطعه‌ها (segments).
غیرمجاز بودن برچسب‌های تعریف‌نشده در حالت بازنشانی.
برچسب label را حتی هنگام پیوندزدن (linking)، به‌عنوان یک برچسب مطلق (اما تعریف‌نشده) تعریف می‌کند.
پایهٔ قطعه (segment base) را برای قطعهٔ ? روی نشانی addr تنظیم می‌کند. ? باید برای قطعه‌های text، data، bss یا zero به‌ترتیب t، d، b یا z باشد.
قطعهٔ text را در نشانی‌ای آغاز می‌کند که وقتی فایل در نشانی addr آغاز شود، نیازی به بازنشانی نباشد. این گزینه بر -bt مقدم است؛ سایر قطعه‌ها همچنان باید با -b تنظیم شوند.
جلوگیری از نمایش فهرست نمادهای سراسری (globals) صادرشده.
تعریف یک ماکروی پیش‌پردازنده در خط فرمان (بخش PREPROCESSOR را ببینید).
افزودن دایرکتوری dir به مسیر شمول (include path) (پیش از XAINPUT؛ بخش ENVIRONMENT را ببینید).
تعریف مجموعه نویسه (charset) خروجی برای رشته‌های نویسه‌ای. موارد پشتیبانی‌شده در حال حاضر عبارتند از ASCII (پیش‌فرض)، PETSCII (اسکی کمودور)، PETSCREEN (کدهای صفحه نمایش کمودور) و HIGH (تنظیم بیت بالا روی تمام نویسه‌ها).
تنظیم نویسهٔ جایگزین پیش‌پردازنده به ?. این گزینه زمانی مفید است که بخواهید هم‌زمان از cpp(1) و پیش‌پردازندهٔ توکار استفاده کنید (بخش PREPROCESSOR را ببینید). ممکن است لازم باشد نویسه‌ها برای شل شما درون گیومه قرار گیرند (مثال: -p'~' )..TP --help نمایش خلاصه‌ای از گزینه‌ها (-? مترادف آن است).
نمایش نسخه برنامه.

مقدمه‌ای بر برنامه‌نویسی به زبان اسمبلی 6502 و نمادهای دستوری (mnemonics) فراتر از دامنه این صفحه راهنما است. از شما دعوت می‌کنیم تا کتاب‌های عالی متعددی را در این زمینه بررسی کنید؛ یک عنوان مفید «Machine Language For Beginners» اثر Richard Mansfield (انتشارات !COMPUTE) است که سیستم‌های ۸ بیتی Atari، Commodore و Apple را پوشش می‌دهد و به طور گسترده در بازار دست دوم موجود است.

برنامه xa هم از کدهای دستوری (opcodes) استاندارد NMOS 6502 و هم از کدهای دستوری Rockwell CMOS استفاده‌شده در 65C02 (R65C02) پشتیبانی می‌کند. با گزینه -w برنامه xa کدهای دستوری 65816 را نیز خواهد پذیرفت. کدهای دستوری ثبت‌نشده (undocumented) در NMOS 6502 عمداً پشتیبانی نمی‌شوند و باید به صورت دستی با استفاده از شبه‌دستور .byte وارد شوند (بخش PSEUDO-OPS را ببینید). به دلیل تداخل میان مجموعه‌های دستورالعمل R65C02 و 65816 با دستورالعمل‌های ثبت‌نشده در NMOS 6502، استفاده از آن‌ها توصیه نمی‌شود.

به طور کلی، xa قالب کم‌وبیش استاندارد اسمبلر 6502 را که توسط MASM و TurboAssembler رایج شد، می‌پذیرد. مقادیر و آدرس‌ها می‌توانند به صورت مقادیر صریح (literals) یا به عنوان عبارت‌ها (expressions) بیان شوند؛ بدین صورت:

123
مقدار ده‌دهی (decimal)
$234
مقدار هگزادسیمال (hexadecimal) (0x234 با -XC پذیرفته می‌شود)
&123
اکتال (octal) (0123 با -XC پذیرفته می‌شود)
%010110
باینری (binary)
*
مقدار فعلی شمارنده برنامه (program counter)

مقدار ASCII هر نویسه درون علامت نقل‌قول مستقیماً در متن برنامه درج می‌شود (مثال: "A" بایت "A" را در جریان خروجی درج می‌کند)؛ همچنین بخش PSEUDO-OPS را ببینید. این رفتار تحت تأثیر مجموعه نویسه (character set) انتخاب‌شده فعلی (در صورت وجود) قرار می‌گیرد.

برچسب‌ها (Labels) مکان‌هایی را در متن برنامه مشخص می‌کنند، درست مانند سایر اسمبلرهای چندگذره (multi-pass). برچسب با هر چیزی که یک کد دستوری نباشد تعریف می‌شود؛ برای مثال، خطی مانند

label1 lda #0

مکان فعلی شمارنده برنامه (و در نتیجه آدرس کد دستوری LDA) را به عنوان label1 تعریف می‌کند. یک برچسب می‌تواند به طور صریح با اختصاص دادن مقدار یک عبارت به آن تعریف شود، مانند

label2 = $d000

که label2 را برابر با آدرس $d000، یعنی شروع بلوک ثبات VIC-II در رایانه‌های Commodore 64 تعریف می‌کند. شمارنده برنامه * نوع خاصی از برچسب در نظر گرفته می‌شود و می‌توان با دستوراتی مانند

* = $c000

به آن مقدار اختصاص داد که شمارنده برنامه را روی مکان ده‌دهی 49152 تنظیم می‌کند. در صورت مشخص شدن گزینه -XCA65 می‌توانید علاوه بر = از := نیز استفاده کنید.

به استثنای شمارنده برنامه، برچسب‌ها را نمی‌توان چندین بار مقداردهی کرد. برای اعلان صریح بازتعریف یک برچسب، یک خط فاصله (-) پیش از آن قرار دهید، مانند:

-label2 = $d020

که label2 را روی ثبات رنگ حاشیه Commodore 64 تنظیم می‌کند. حوزه دید (scope) یک برچسب تحت تأثیر بلوکی است که در آن قرار دارد (دستورالعمل‌های بلوک را در PSEUDO-OPS ببینید). یک برچسب را می‌توان با گزینه خط فرمان -L نیز به صورت ثابت و صریح تعیین کرد.

بازتعریف یک برچسب، کدهای قبلاً اسمبل‌شده‌ای را که از مقدار پیشین استفاده کرده‌اند تغییر نمی‌دهد. بنابراین، از آنجا که شمارنده برنامه نوع خاصی از برچسب است، تغییر شمارنده برنامه به مقداری کمتر، ترتیب کدهایی را که پیش‌تر اسمبل شده‌اند تغییر نمی‌دهد و تغییر آن به مقداری بیشتر نیز فاصله‌گذاری (padding) برای قرار دادن کدهای بعدی در مکان جدید ایجاد نمی‌کند. این رفتاری عمدی برای تسهیل تولید کدهای جابه‌جاشونده (relocatable) و مستقل از مکان (position-independent) است، اما ممکن است با سایر اسمبلرهایی که از این رفتار برای پیوند دادن (linking) استفاده می‌کنند متفاوت باشد. با این حال، می‌توان از شبه‌دستورها برای شبیه‌سازی رفتار سایر اسمبلرها و استفاده از xa به عنوان یک پیونددهنده (linker) استفاده کرد؛ بخش‌های PSEUDO-OPS و LINKING را ببینید.

اگر -XCA65 یا -a مشخص شده باشد، برچسب‌های «بی‌نام» را می‌توان با : تعیین کرد (یعنی بدون نام برچسب، فقط یک دونقطه)؛ سپس پرش‌ها و انشعاب‌ها می‌توانند با یک دونقطه و علامت‌های مثبت برای انشعاب رو به جلو یا علامت‌های منفی برای انشعاب رو به عقب به این برچسب‌های بی‌نام ارجاع دهند. برای مثال (از مستندات ca65(1)):


: lda (ptr1),y ; #1
cmp (ptr2),y
bne :+ ; -> #2
tax
beq :+++ ; -> #4
iny
bne :- ; -> #1
inc ptr1+1
inc ptr2+1
bne :- ; -> #1


: bcs :+ ; #2 -> #3
ldx #$FF
rts


: ldx #$01 ; #3
: rts ; #4

علاوه بر این، در حالت -XCA65، می‌توان از برچسب‌های محلی «ارزان» (cheap) که با پیشوند @ مشخص می‌شوند استفاده کرد. این برچسب‌های موقت تنها میان دو برچسب عادی وجود دارند و با رسیدن به برچسب عادی بعدی به طور خودکار از حوزه دید خارج می‌شوند. این ویژگی امکان می‌دهد تا با دقتی معقول، نام‌های متداول برچسب مانند "loop" را دوباره استفاده کرد.

برای آن دسته از دستورالعمل‌هایی که انباره (accumulator) آرگومان ضمنی آن‌ها است (مانند asl و lsr؛ inc و dec در R65C02 و غیره)، شیوه تعیین صریح انباره با a ضرورتی ندارد، زیرا در صورت نبود آرگومان صریح، ساختار مناسب انتخاب خواهد شد. در واقع، جهت سازگاری با نحوه مدیریت برچسب‌ها، اگر برچسبی به نام a وجود داشته باشد، کدی تولید می‌شود که به آن برچسب به عنوان یک مکان حافظه ارجاع می‌دهد نه به انباره؛ در غیر این صورت، اسمبلر خطا خواهد گرفت.

برچسب‌ها و کدهای دستوری می‌توانند عبارت‌ها (expressions) را به عنوان آرگومان‌های خود بپذیرند تا مقادیر محاسباتی را مجاز سازند، و خود نیز می‌توانند به سایر برچسب‌ها و/یا شمارنده برنامه ارجاع دهند. یک عبارت مانند lab1+1 (که روی مقدار فعلی برچسب lab1 عمل کرده و یک واحد به آن می‌افزاید) می‌تواند از عملوندهای زیر استفاده کند که از بالاترین اولویت به پایین‌ترین اولویت مرتب شده‌اند:.TP 8 * ضرب (اولویت ۱۰)

/
تقسیم صحیح (اولویت ۱۰)
+
جمع (اولویت ۹)
-
تفریق (۹)
<<
شیفت به چپ (۸)
>>
شیفت به راست (۸)
>= =>
بزرگ‌تر یا مساوی (۷)
>
بزرگ‌تر (۷)
<= =<
کوچک‌تر یا مساوی (۷)
<
کوچک‌تر (۷)
=
مساوی با (۶)؛ == نیز پذیرفته می‌شود
<> ><
نامساوی (۶)؛ != نیز پذیرفته می‌شود
&
عملگر AND بیتی (۵)
^
عملگر XOR بیتی (۴)
|
عملگر OR بیتی (۳)
&&
عملگر AND منطقی (۲)
||
عملگر OR منطقی (۱)

پرانتزها معتبر هستند. هنگام بازتعریف یک برچسب (label)، ترکیب عملگرهای حسابی یا بیتی با عملگر مساوی (=) مانند += و نظایر آن معتبر است؛ برای مثال:

-redeflabel += (label12/4)

به‌طور معمول، xa تلاش می‌کند مقدار عملوند را تشخیص دهد و (هنگام ارجاع به یک مکان از حافظه) در صورت تناسب و پشتیبانی توسط کد دستور (opcode) خاص، از آدرس‌دهی صفحه صفر (zero page)، ۱۶ بیتی یا (برای 65816) ۲۴ بیتی استفاده کند. این کار کدی کوچک‌تر و سریع‌تر تولید می‌کند و تقریباً همیشه ارجح است.

با این وجود، می‌توانید از این عملگرهای پیشوندی برای اجبار در تفسیر خاصی از عملوند استفاده کنید. مواردی که نتیجه‌ای هشت‌بیتی تولید می‌کنند می‌توانند در حالت‌های آدرس‌دهی ۸ بیتی، مانند فوری (immediate) و صفحه صفر (zero page) نیز به کار روند.

<
بایت پایین (low byte) عبارت؛ برای مثال: lda #<vector
>
بایت بالا (high byte) عبارت
!
در شرایطی که عبارت می‌تواند هم به‌عنوان یک مقدار مطلق (absolute) و هم صفحه صفر (zero page) درک شود، برای آن دسته از کدهای دستوری که از آن پشتیبانی می‌کنند، تلاشی برای بهینه‌سازی به یک آرگومان صفحه صفر انجام نده (یعنی به‌صورت کلمه ۱۶ بیتی نگه‌دار)
@
تفسیر به‌صورت مقدار ۲۴ بیتی برای 65816، حتی اگر از ۲۴ بیت کوچک‌تر باشد (باید گزینه خط فرمان -w مشخص شده باشد و نباید -XCA65 مشخص شده باشد)
`
اجبار به بهینه‌سازی بیشتر، حتی اگر طول دستورالعمل به‌طور مطمئن قابل تعیین نباشد (ببینید NOTES'N'BUGS)

عبارت‌ها می‌توانند به‌عنوان آرگومان‌های کدهای دستور (opcodes) یا در پیش‌پردازنده بیایند (برای نحوه نحو به PREPROCESSOR مراجعه کنید). برای مثال:

lda label2+1

مقدار موجود در label2+1 را می‌گیرد (با در نظر گرفتن مقدار برچسب قبلی ما، این مقدار $d021 خواهد بود)، و به‌صورت $ad $21 $d0 روی دیسک اسمبل می‌شود. به همین ترتیب،

lda #<label2

پایین‌ترین ۸ بیت label2 (یعنی $20) را می‌گیرد و آن‌ها را به انباشتگر (accumulator) اختصاص می‌دهد (و دستورالعمل را به‌صورت $a9 $20 روی دیسک اسمبل می‌کند).

کامنت‌ها با یک نقطه ویرگول (;) مشخص می‌شوند، مانند

;this is a comment

آن‌ها همچنین می‌توانند به شیوه زبان C با استفاده از /* */ و // مشخص شوند که در سطح PREPROCESSOR درک می‌شوند (رجوع شود به آن).

به‌طور معمول، دونقطه (:) دستورها (statements) را از هم جدا می‌کند، مانند

label4 lda #0:sta $d020

یا

label2: lda #2

(به استفاده از دونقطه برای تعیین یک برچسب توجه کنید، مشابه برخی اسمبلرهای دیگر، که xa نیز آن را با یا بدون دونقطه متوجه می‌شود). این موضوع در مورد کامنت‌های با نقطه ویرگول نیز صدق می‌کند، به‌گونه‌ای که

; a comment:lda #0

به‌عنوان یک کامنت و به دنبال آن یک کد دستور تفسیر می‌شود. برای جلوگیری از این رفتار، از حالت سازگاری -XMASM استفاده کنید تا دونقطه درون کامنت‌ها مجاز شود؛ این رفتار ممکن است در نسخه‌های آینده به حالت پیش‌فرض تبدیل شود. جداسازی دستورها با دونقطه روی کامنت‌های /* */ و // که در سطح پیش‌پردازنده مدیریت می‌شوند اعمال نمی‌شود (رجوع شود به آن)..SH "شبه‌دستورها (PSEUDO-OPS)"

Pseudo-ops کدهای عملیاتی کاذبی هستند که توسط اسمبلر برای مشخص کردن دستورهای متا یا درون‌خطی استفاده می‌شوند. همانند بیشتر اسمبلرها، xa مجموعه‌ای غنی از آن‌ها را داراست.

.byt value1,value2,value3,...
رشته‌ای از بایت‌ها را مشخص می‌کند که مستقیماً در شیء اسمبل‌شده قرار می‌گیرند. آرگومان‌ها می‌توانند عبارت باشند. هر تعداد بایت را می‌توان تعیین کرد.
.asc "text1" ,"text2",...
یک رشته نویسه‌ای را مشخص می‌کند که در شیء اسمبل‌شده درج خواهد شد. رشته‌ها بر اساس مجموعه نویسه تعیین‌شده کنونی تفسیر می‌شوند؛ برای مثال، اگر ASCII مشخص شده باشد، به عنوان ASCII رندر می‌شوند، و اگر PETSCII مشخص شده باشد، به معادل Commodore ASCII ترجمه می‌گردند. سایر ASCIIهای غیر استاندارد مانند ATASCII برای رایانه‌های Atari باید از نویسه‌های معادل ASCII استفاده کنند؛ نویسه‌های گرافیکی و کنترلی باید برای نویسه دقیقی که می‌خواهید، به‌طور صریح با استفاده از .byt مشخص شوند. توجه داشته باشید هنگام مشخص کردن آرگومان یک opcode، استفاده از .asc لازم نیست؛ نویسه درون نقل‌قول می‌تواند به سادگی درج شود (مانند lda #"A" ) و همچنین تحت تأثیر مجموعه نویسه کنونی قرار می‌گیرد. هر تعداد رشته نویسه‌ای را می‌توان تعیین کرد.

.byt و .asc مترادف هستند، بنابراین می‌توانید مواردی مانند .byt $43, 22, "a character string" را ترکیب کرده و نتیجه مورد انتظار را بگیرید. رشته تابع مجموعه نویسه جاری است، اما بایت‌های باقی‌مانده بدون تغییر درج می‌شوند.

.aasc "text1" ,"text2",...
رشته نویسه‌ای را مشخص می‌کند که همیشه صرف‌نظر از مجموعه نویسه کنونی، در ASCII واقعی رندر می‌شود. مانند .asc، با .byt مترادف است.
.word value1,value2,value3...
رشته‌ای از کلمات ۱۶ بیتی را برای قرار گرفتن در شیء اسمبل‌شده در قالب little-endian پردازنده 6502 (یعنی بایت کم‌ارزش/بایت پرارزش) مشخص می‌کند. آرگومان‌ها می‌توانند عبارت باشند. هر تعداد کلمه را می‌توان تعیین کرد.
.dsb length,fillbyte
یک بلوک داده را مشخص می‌کند؛ در مجموع به تعداد length تکرار از fillbyte در شیء اسمبل‌شده درج خواهد شد. برای مثال، .dsb 5,$10 پنج بایت، که هر یک برابر با مقدار دهدهی ۱۶ است، در شیء درج می‌کند. آرگومان‌ها می‌توانند عبارت باشند. اگر تنها یک آرگومان ارائه شود، به عنوان تعداد بایت‌های تهی (null) برای درج در نظر گرفته می‌شود. برای نحوه استفاده از این شبه‌دستور جهت پیوند چند شیء، به LINKING مراجعه کنید.
.bin offset,length,"filename"
یک فایل باینری را بدون تفسیر بیشتر که با filename مشخص شده است، از آفستِ offset (نسبت به ابتدای فایل) به اندازه length بایت به صورت درون‌خطی قرار می‌دهد. این به شما امکان می‌دهد داده‌هایی مانند یک فایل شیء از قبل اسمبل‌شده یا یک تصویر یا ساختار داده باینری دیگر را مستقیماً درون شیء این فایل درج کنید. اگر length صفر باشد، طول filename، منهای آفست به جای آن استفاده می‌شود. آرگومان‌ها می‌توانند عبارت باشند. برای نحوه استفاده از این شبه‌دستور جهت پیوند چند شیء، به LINKING مراجعه کنید.
.(
یک بلوک جدید برای محدوده‌بندی (scoping) باز می‌کند. درون یک بلوک، تمامی برچسب‌های تعریف‌شده محلی برای همان بلوک و زیربلوک‌های آن هستند، و به محض بسته شدن بلوک دربرگیرنده، از حوزه دسترسی خارج می‌شوند (یعنی حوزه لغوی دارند). تمام برچسب‌های تعریف‌شده خارج از بلوک همچنان در درون آن قابل مشاهده‌اند. برای اعلان صریح یک برچسب سراسری در داخل یک بلوک، قبل از نام برچسب + قرار دهید یا قبل از آن & بگذارید تا فقط درون سطح قبلی اعلان شود (یا به صورت سراسری، اگر تنها در عمق یک سطح هستید). شانزده سطح از محدوده‌بندی مجاز است.
.block به عنوان مترادفی برای .( پذیرفته می‌شود، و همچنین .proc (اما نمی‌توانید بر خلاف ca65 یک نام حوزه صریح تعیین کنید؛ فقط بلوک‌های ناشناس پشتیبانی می‌شوند).
.)
یک بلوک را می‌بندد. .bend یا .endproc به عنوان مترادف پذیرفته می‌شوند.
.as .al .xs .xl
فقط در حالت 65816 (با تعیین گزینه -w) مرتبط هستند. این شبه‌دستورها مشخص می‌کنند که چه اندازه‌ای برای آکومولاتور و ثبات‌های X/Y باید در دستورالعمل‌های بعدی استفاده شود؛ .as و .xs به ترتیب عملوندهای ۸ بیتی را برای آکومولاتور و ثبات‌های ایندکس تعیین می‌کنند، و .al و .xl عملوندهای ۱۶ بیتی را تنظیم می‌نمایند. این شبه‌دستورها عمداً دستورالعمل‌های sep و rep را به طور خودکار صادر نمی‌کنند تا پهنای مشخص‌شده را در CPU تنظیم نمایند؛ بیت‌های پردازنده را بر اساس نیاز خود تنظیم کنید، یا ساخت یک ماکرو را در نظر بگیرید. اگر -w مشخص نشده باشد، .al و .xl خطا تولید می‌کنند.
.assert expression,"message"
عبارت expression را ارزیابی می‌کند و در صورتی که نادرست باشد (یعنی برابر با صفر شود)، message را به عنوان یک خطای مهلک چاپ کرده و بی‌درنگ اسمبل کردن را خاتمه می‌دهد. برای مثال، یک بلوک از کد اسمبلی که حافظه ROM بالایی ایجاد می‌کند، ممکن است دارای عبارت زیر باشد:
.assert *<$fffa, "hit vectors"
تا اطمینان حاصل شود که کد اسمبل‌شده به بردارهای بالایی 6502 سرایت نمی‌کند. اگر کد قبلی بیش از حد طولانی باشد، گزاره نادرست خواهد بود و این شرایط به شکلی کنترل‌شده شناسایی می‌شود. هر عملیاتی می‌تواند به عنوان بخشی از عبارت استفاده شود، از جمله مقایسه‌های منطقی مانند =، ==، <، <=، >، >=، != و <>.
.include filename
فایل دیگری را به جای این شبه‌دستور وارد می‌کند، گویی پیش‌پردازنده این کار را با دستورالعمل #include انجام داده است (به PREPROCESSOR مراجعه کنید)، اما در مرحله اسمبلر، پس از آن‌که پیش‌پردازش قبلاً انجام گرفته است.

شبه‌دستور زیر برای حالت فهرست‌سازی (listing) اعمال می‌شود.

.listbytes number
در خروجی فهرست‌سازی، حداکثر تعداد بایت‌های هگزادسیمال را که باید در فهرست برای شبه‌دستورهایی مانند .byt چاپ شوند تعیین می‌کند؛ که مقدار پیش‌فرض آن ۸ است. آرگومان ویژه unlimited هیچ حد بالایی تعیین نمی‌کند. اگر حالت فهرست‌سازی غیرفعال باشد، این شبه‌دستور هیچ تأثیر قابل مشاهده‌ای ندارد.

شبه‌دستورهای زیر در درجه اول برای اشیاء جابجایی‌پذیر .o65 اعمال می‌شوند. بحث کامل در مورد قالب جابجایی‌پذیر خارج از محدوده این صفحه راهنما است؛ برای جدیدترین مشخصات به http://www.6502.org/users/andre/o65 مراجعه کنید.

.text .data .bss .zero
این شبه‌دستورها بین بخش‌های مختلف جابجا می‌شوند؛ .text بخش کد واقعی است، .data بخش داده است، .bss فضای برچسب مقداردهی‌نشده برای تخصیص است و .zero فضای صفحه صفر (zero page) مقداردهی‌نشده برای تخصیص است. در .bss و .zero، فقط برچسب‌ها ارزیابی می‌شوند. این شبه‌دستورها در حالت‌های جابجایی‌پذیر و مطلق معتبر هستند..TP .code برای سازگاری با ca65، این دستور در حال حاضر به .text نگاشت شده است.
.zeropage
برای سازگاری با ca65، این دستور در حال حاضر به .zero نگاشت شده است.
.align value
قطعهٔ (segment) فعلی را به یک مرز بایتی (۲، ۴ یا ۲۵۶) همان‌طور که توسط value مشخص شده تراز می‌کند (و هنگامی که حالت بازآرایی [relocating] فعال باشد، آن را در سرایند قرار می‌دهد). مقادیر دیگر باعث ایجاد خطا می‌شوند.
.fopt type, value1, value2, value3, ...
مانند .byt/.asc عمل می‌کند، با این تفاوت که مقادیر به عنوان گزینه‌های فایل در فایل شیء تعبیه می‌شوند. آرگومان type برای مشخص کردن گزینهٔ فایلِ مورد ارجاع به کار می‌رود. جدولی از این گزینه‌ها در توصیف قالب فایل بازآرایی‌پذیر o65 آمده است. سایر گزینه‌ها به عنوان مقادیری برای درج تفسیر می‌شوند. هر تعداد مقداری را می‌توان تعیین کرد که می‌توانند رشته نیز باشند.
.import label1, label2, label3, ...
برچسب‌های مشخص‌شده را به عنوان برچسب‌های سراسری تعریف می‌کند که در طول مرحلهٔ پیوند (link) همانند پارامتر خط فرمان -L وارد (import) و حل (resolve) می‌شوند.
.importzp label1, label2, label3, ...
مشابه .import، با این تفاوت که تنها برچسب‌های zeropage (یعنی مقادیر بایتی) را وارد می‌کند.

xa پیش‌پردازنده‌ای بسیار شبیه به پیش‌پردازندهٔ زبان C یعنی cpp(1) را پیاده‌سازی می‌کند و بسیاری از جزئیات و ریزه‌کاری‌ها برای هر دو صدق می‌کنند. برای نمونه، همانند C، استفاده از /* */ برای نشانگرهای توضیحات در xa نیز پشتیبانی می‌شود و همچنین استفاده از اسلش دوگانهٔ // برای توضیحات مجاز است. پیش‌پردازنده همچنین از خطوط ادامه‌دار پشتیبانی می‌کند، یعنی خطوطی که به یک بک‌اسلش (\) ختم می‌شوند؛ در این حالت خط بعدی به آن متصل می‌شود، گویی هیچ خط جدید جداکننده‌ای وجود ندارد. این مورد نیز در سطح پیش‌پردازنده مدیریت می‌شود.

به دلایل محدودیت حافظه و پیچیدگی، تمام گسترهٔ نحو cpp(1) به‌طور کامل پشتیبانی نمی‌شود. به‌ویژه، تعاریف ماکرو نمی‌توانند ارجاع به جلو داشته باشند (یعنی یک تعریف ماکرو تنها می‌تواند به ماکرویی ارجاع دهد که قبلاً تعریف شده است)، به جز ماکروهای تابعی که ارزیابی بازگشتی در آن‌ها پشتیبانی می‌شود؛ برای مثال، برای #define WW AA ، AA باید از پیش تعریف شده باشد. برخی دستورات (directive) دیگر پشتیبانی نمی‌شوند، اکثر ماکروهای پیش‌تعریف‌شدهٔ استاندارد نیز موجود نیستند، و محدودیت‌های دیگری نیز بر ارزیابی و طول خط اعمال شده است. از آنجا که نگه‌دارندگان xa می‌دانند برخی فایل‌ها به پیش‌تجزیهٔ پیچیده‌تری نسبت به آنچه پیش‌پردازندهٔ داخلی می‌تواند ارائه دهد نیاز دارند، این پیش‌پردازنده خروجیِ خط/نام‌فایل/پرچم‌های سبک cpp(1) را می‌پذیرد. هنگامی که این خطوط در فایل ورودی دیده شوند، xa با آن‌ها همان‌گونه رفتار می‌کند که cc رفتار می‌کرد، با این تفاوت که پرچم‌ها نادیده گرفته می‌شوند. xa به دلایل مربوط به تجزیه، فایل‌ها را از ورودی استاندارد نمی‌پذیرد، بنابراین باید خروجی cpp(1) خود را در یک فایل موقت میانی ذخیره کنید، مانند

cc -E test.s > test.xa
xa test.xa

نیازی به ارسال آرگومان‌های ویژه به xa نیست؛ وجود خروجی cpp(1) به‌طور خودکار تشخیص داده می‌شود.

توجه داشته باشید که عبور دادن فایل شما از cpp(1) ممکن است با دستورات پیش‌پردازندهٔ خودِ xa تداخل ایجاد کند. در این صورت، برای پنهان کردن دستورات از cpp(1)، از گزینهٔ -p برای تعیین نویسه‌ای جایگزین به‌جای # استفاده کنید، مانند مدک (تایلد) (مثلاً -p'~'). با مشخص کردن این گزینه و آرگومان، برای نمونه به جای #include، علاوه بر #include می‌توانید از ~include نیز استفاده کنید (که با فرض باقی ماندن پس از عبور از cpp(1)، همچنان توسط پیش‌پردازندهٔ xa پذیرفته خواهد شد). هر نویسه‌ای را می‌توان استفاده کرد، هرچند انتخاب‌های واقعاً نامتعارف ممکن است در حین تجزیه منجر به اشکالات عجیب یا کلافه‌کننده‌ای شوند. همچنین می‌توانید از این گزینه برای به تعویق انداختن دستورات پیش‌پردازنده‌ای که ممکن است cpp(1) خیلی زود آن‌ها را تفسیر کند استفاده کنید تا فایل واقعاً جهت پردازش به خودِ xa برسد.

ماکروهای پیش‌تعریف‌شدهٔ زیر پشتیبانی می‌شوند، مگر اینکه -XXA23 مشخص شده باشد:

نسخهٔ اصلی (major) فعلی xa.
نسخهٔ فرعی (minor) فعلی xa.

دستورات پیش‌پردازندهٔ زیر پشتیبانی می‌شوند:

#include "filename"
محتویات فایل filename را در این موقعیت درج می‌کند. اگر فایل پیدا نشود، با استفاده از مسیرهای تعیین‌شده توسط گزینهٔ خط فرمان -I یا متغیر محیطی XAINPUT (به بخش مربوطه مراجعه کنید) جستجو می‌شود. پس از درج، این فایل نیز برای یافتن دستورات پیش‌پردازنده تجزیه خواهد شد.
#echo comment
توضیح comment را در فایل گزارش خطا (errorlog) که با گزینهٔ خط فرمان -e تعیین می‌شود، درج می‌کند.
#print expression
مقدار عبارت expression را محاسبه کرده و در فایل گزارش خطا چاپ می‌کند.
#error message
پیام را به عنوان یک خطا نمایش داده و فرایند اسمبل کردن را متوقف می‌کند.
#define DEFINE text
ماکروی DEFINE را با متن text برابر قرار می‌دهد، به‌طوری که هر جا DEFINE در کد منبع اسمبلی ظاهر شود، text به جای آن جایگزین می‌گردد (درست مانند رفتاری که cpp(1) دارد). علاوه بر این، #define می‌تواند همانند cpp(1) ماکروهای تابعی را مشخص کند، به‌گونه‌ای که دستوری مانند #define mult(a,b) ((a)*(b)) نتیجهٔ مورد انتظار را در هر جایی که عبارتی به فرم mult(a,b) در کد منبع بیاید تولید کند. این مورد را می‌توان در خط فرمان نیز با گزینهٔ -D مشخص کرد. آرگومان‌های یک ماکروی تابعی، برخلاف دیگر #defineها، می‌توانند به‌طور بازگشتی ارزیابی شوند؛ پیش‌پردازنده پیش از اعلام خطا، تا ده بار تلاش می‌کند هر آرگومانی را که به تعریف پیش‌پردازندهٔ دیگری ارجاع می‌دهد، مجدداً ارزیابی کند.

دستورات زیر شرطی هستند. اگر شرط برقرار نباشد، کد منبع بین دستور و #endif پایانی آن حذف شده و اسمبل نمی‌شود. تا پانزده سطح تو در تویی پشتیبانی می‌شود.

#ifdef DEFINE
تنها در صورتی درست (True) است که ماکروی DEFINE تعریف شده باشد..TP #ifndef DEFINE حالت معکوس؛ تنها در صورتی درست (true) است که ماکروی DEFINE قبلاً تعریف نشده باشد.
#if expression
در صورتی درست است که عبارت expression به مقداری غیرصفر ارزیابی شود. expression می‌تواند به ماکروهای دیگر نیز ارجاع دهد.
#iflused label
در صورتی درست است که برچسب label استفاده شده باشد (اما لزوماً با یک مقدار مقداردهی نشده باشد). این دستور روی برچسب‌ها کار می‌کند، نه ماکروها!
#ifldef label
در صورتی درست است که برچسب label تعریف شده و مقداری به آن اختصاص یافته باشد. این دستور روی برچسب‌ها کار می‌کند، نه ماکروها!
#else
مسیر جایگزین را برای یک بلوک شرطی پیاده‌سازی می‌کند.
#endif
یک بلوک شرطی را می‌بندد.

بلوک‌های شرطی بسته‌نشده در انتهای فایل‌های ضمیمه‌شده (included) هشدار تولید می‌کنند؛ بلوک‌های شرطی بسته‌نشده در انتهای فرایند اسمبل، خطا ایجاد می‌کنند.

#iflused و #ifldef برای ساختن یک کتابخانه بر پایهٔ برچسب‌ها مفید هستند. برای نمونه، ممکن است از چیزی شبیه به این در کد کتابخانهٔ خود استفاده کنید:

#iflused label
#ifldef label
#echo label already defined, library function label cannot be inserted
#else
label /* your code */
#endif
#endif

xa به سمت تولید باینری‌های ترتیبی گرایش دارد. کدها دقیقاً به ترتیب خارج می‌شوند، حتی اگر شمارندهٔ برنامه (program counter) روی مکانی پایین‌تر از کدهای اسمبل‌شدهٔ قبلی تنظیم شده باشد، و در صورتی که شمارندهٔ برنامه روی مکان بالاتری تنظیم شود، فاصله‌گذاری (padding) به‌طور خودکار درج نمی‌شود. تغییر مکان برنامه تنها برچسب‌های جدید را برای کدهایی که پس از آن تولید می‌شوند تغییر می‌دهد؛ کدهای تولیدشدهٔ قبلی بدون تغییر باقی می‌مانند. خوشبختانه، برای بسیاری از فایل‌های شیء این قواعد اثری بر روند تولید آن‌ها ندارد.

با این حال، ممکن است برخی کاربردها نیازمند تولید یک فایل شیء ساخته‌شده از چندین مؤلفه و/یا زیرماژول قبلاً تولیدشده باشند که باید در مکان‌های خاصی از حافظه قرار گیرند. با مقدار کمی مشخصات اضافی، می‌توان از xa برای این منظور نیز استفاده کرد.

اولین روش برای انجام این کار، استفاده از قالب o65 برای ساخت اشیاء با قابلیت جابه‌جایی (relocatable) است که به‌نوبهٔ خود می‌توانند توسط ldo65(1) (رجوع شود به آن) پیوند داده شوند.

روش دوم شامل کدهای اسمبل‌شده، یا درج فایل‌های شیء یا داده‌ای از قبل ساخته‌شده با .bin است، که در آن از شبه‌دستورهای .dsb با آرگومان‌های عبارتی محاسباتی برای درج هرگونه فاصله‌گذاری لازم بین آن‌ها، به ترتیبی که قرار است در حافظه قرار گیرند، استفاده می‌شود. این مثال را در نظر بگیرید:


.word $1000
* = $1000


; this is your code at $1000
part1 rts
; this label marks the end of code
endofpart1


; DON'T PUT A NEW .word HERE!
* = $2000
.dsb (*-endofpart1), 0
; yes, set it again
* = $2000


; this is your code at $2000
part2 rts

این مثال، که برای ریزرایانه‌های Commodore با استفاده از آدرس شروع ۱۶ بیتی نوشته شده است، شامل دو «ماژول» است: یک بلوک کد در $1000 (4096)، که با کد میان برچسب‌های part1 و endofpart1 مشخص شده است، و یک بلوک دوم در $2000 (8192) که از برچسب part2 آغاز می‌شود.

فاصله‌گذاری توسط شبه‌دستور .dsb بین دو ماژول محاسبه می‌شود. توجه داشته باشید که شمارندهٔ برنامه بر روی آدرس جدید تنظیم شده و سپس یک عبارت محاسباتی، تعداد بایت‌های پرکننده مناسب را از انتهای کد اسمبل‌شده در بخش ۱ تا آدرس جدید شمارندهٔ برنامه درج می‌کند. از آنجا که این کار خود شمارندهٔ برنامه را به جلو می‌برد، شمارندهٔ برنامه دوباره بازنشانی شده و فرایند اسمبل ادامه می‌یابد.

هنگامی که شیءِ تولیدشده توسط این فایل مبدأ بارگذاری می‌شود، یک دستورالعمل rts در آدرس 4096 و دستور دیگری در آدرس 8192 وجود خواهد داشت که بایت‌های تهی (null) بین آن‌ها قرار گرفته‌اند.

اگر لازم باشد یکی از این نواحی به جای کد اسمبلی شامل یک فایل از قبل ساخته‌شده باشد، کافی است از شبه‌دستور .bin برای بارگذاری هر بخش از فایل که مورد نیاز است در خروجی استفاده کنید. محاسبهٔ آدرس‌ها و تعداد بایت‌های پرکنندهٔ لازم نیز به همان روش انجام می‌شود.

اگرچه در این مثال از خود شمارندهٔ برنامه برای محاسبهٔ تفاوت بین آدرس‌ها استفاده شد، اما می‌توانید از هر برچسبی برای این منظور استفاده کنید؛ البته با این یادآوری که تنها شمارندهٔ برنامه تعیین می‌کند که آدرس‌های نسبی در داخل کد اسمبل‌شده در کجا حل‌وفصل شوند..SH "محیط (ENVIRONMENT)"

xa در صورت وجود متغیرهای محیطی زیر، از آن‌ها استفاده می‌کند:

مسیر فایل‌های include؛ اجزا باید با «,» از یکدیگر جدا شوند.
مسیر فایل خروجی.

دستورالعمل‌های R65C02 یعنی ina (که اغلب به‌صورت inc a نمایش داده می‌شود) و dea (dec a) باید به ترتیب به‌صورت دستورالعمل‌های ساده‌ی inc و dec نوشته شوند.

دستورالعمل‌های 65816 یعنی mvn و mvp از دو پارامتر هشت بیتی استفاده می‌کنند؛ این‌ها تنها دستورالعمل‌ها در کل مجموعه‌دستورالعمل هستند که چنین رفتاری دارند. نسخه‌های قدیمی‌ترِ xa یک مقدار مطلق ۱۶ بیتی می‌گرفتند. از نسخه 2.4.0، این نحو قدیمی دیگر پذیرفته نیست.

برچسب‌های تعریف‌شده رو به جلو -- یعنی برچسب‌هایی که پس از پردازش دستورالعمل جاری تعریف می‌شوند -- حتی اگر در نهایت در مکانی از صفحه‌صفر (zero page) تعریف شوند، نمی‌توانند به دستورالعمل‌های صفحه‌صفر بهینه‌سازی شوند، زیرا اسمبلر در گذر اول که طول دستورالعمل محاسبه می‌شود، مقدار برچسب را از پیش نمی‌داند. در گذر دوم، در صورتی که دستوری به دلیل این محدودیت نتوانسته بهینه‌سازی شود در حالی که امکانش بود، یک هشدار صادر خواهد شد. (بدیهی است که این موضوع برای دستورالعمل‌های انشعاب یا پرش صدق نمی‌کند زیرا به هر حال قابل بهینه‌سازی نیستند، و آن دسته از دستورالعمل‌هایی که فقط می‌توانند یک پارامتر ۸ بیتی بگیرند، همواره به یک مقدار ۸ بیتی تبدیل خواهند شد.) اگر تعریف برچسب پیش از دستورالعمل به شکل دیگری ممکن نباشد، تا زمانی که دستورالعمل پشتیبانی کند، می‌توان از پیشوند بک‌تیک ` برای اجبار بهینه‌سازی بیشتر، صرف‌نظر از محل تعریف برچسب، استفاده کرد. با این حال، اجبار بی‌رویه می‌تواند خطرات زیادی به همراه داشته باشد و توصیه نمی‌شود؛ برای جلوگیری از این کار، اسمبلر در موقعیت‌های حالت آدرس‌دهی که هیچ ابهامی در آن‌ها وجود ندارد، مانند شاخص‌دار غیرمستقیم (indirect indexed)، انشعاب و غیره، به استفاده از آن اعتراض خواهد کرد.

file65(1), ldo65(1), reloc65(1), uncpk(1), dxa(1)

این صفحه راهنما توسط David Weinehall <tao@acc.umu.se>، Andre Fachat <fachat@web.de> و Cameron Kaiser <ckaiser@floodgap.com> نوشته شده است. بسته اصلی xa کپی‌رایت (C)1989-1997 متعلق به Andre Fachat است. تغییرات تکمیلی (C)1989-2024 متعلق به Andre Fachat، Jolse Maginnis، David Weinehall و Cameron Kaiser است. نگهدارنده رسمی Cameron Kaiser است.

هورا برای ما؟

http://www.floodgap.com/retrotech/xa

5 March 2024