คำสั่งการชุมนุม EXIT – ออกจากไฟล์ EQU – ตั้งชื่อให้กับนิพจน์

ตัวประกอบ MASM, TASM และ WASM แตกต่างกัน อย่างไรก็ตาม การสร้างโปรแกรมง่ายๆ สำหรับพวกเขานั้นแทบไม่มีความแตกต่างเลย ยกเว้นชุดประกอบและการเชื่อมโยงเอง

ดังนั้นโปรแกรมแรกของเราสำหรับ MASM, TASM และ WASM ซึ่งเอาท์พุต ตัวอักษรภาษาอังกฤษ"A" ที่ตำแหน่งเคอร์เซอร์ปัจจุบัน ซึ่งก็คือทางด้านซ้าย มุมบนหน้าจอ:

โมเดลจิ๋ว .code ORG 100h เริ่มต้น: MOV AH,2 MOV DL,41h INT 21h INT 20h END start ข้อความนี้สามารถพิมพ์เป็นภาษาง่ายๆ ใดก็ได้ โปรแกรมแก้ไขข้อความ- ตัวอย่างเช่นใน NotePad จาก WINDOWS (แต่ไม่ใช่ใน Word หรืออันที่ "ซับซ้อน" อื่น ๆ ) อย่างไรก็ตาม ฉันขอแนะนำโปรแกรมแก้ไขข้อความ "ขั้นสูง" ที่มีการเน้นไวยากรณ์ เช่น PSPad (ดูหัวข้อ) จากนั้นเราจะบันทึกไฟล์นี้ด้วยนามสกุล .asm เช่น ในโฟลเดอร์ MYPROG ลองเรียกไฟล์ atest ดังนั้นเราจึงได้: C:\MYPROG\atest.asm

บันทึก
โปรดทราบว่าในคำสั่งแรกเราเขียน 2 แทนที่จะเป็น 02h MASM, TASM และ WASM เช่นเดียวกับ Emu8086 อนุญาตให้มี "เสรีภาพ" ดังกล่าว แม้ว่าคุณจะสามารถเขียน 02h ได้ แต่จะไม่มีข้อผิดพลาด

คำอธิบายสำหรับโปรแกรม:

.โมเดลจิ๋ว– บรรทัดที่ 1. คำสั่ง .model กำหนดโมเดลหน่วยความจำสำหรับประเภทไฟล์เฉพาะ ในกรณีของเรา นี่คือไฟล์ที่มี ส่วนขยาย .COMดังนั้นเราจึงเลือกโมเดลขนาดเล็กที่รวมโค้ด ข้อมูล และสแต็กเซ็กเมนต์เข้าด้วยกัน โมเดลจิ๋วได้รับการออกแบบเพื่อสร้างไฟล์ประเภท COM

.รหัส– บรรทัดที่ 2. คำสั่งนี้เริ่มต้นส่วนของรหัส

องค์กร 100 ชม– บรรทัดที่ 3. คำสั่งนี้ตั้งค่าตัวนับโปรแกรมเป็น 100h เนื่องจากเมื่อโหลดไฟล์ COM ลงในหน่วยความจำ DOS จะจัดสรร 256 ไบต์แรกให้กับบล็อกข้อมูล PSP ( เลขทศนิยม 256 เท่ากับ 100h ฐานสิบหก) รหัสโปรแกรมจะอยู่หลังบล็อกนี้เท่านั้น โปรแกรมทั้งหมดที่คอมไพล์เป็นไฟล์ประเภท COM จะต้องเริ่มต้นด้วยคำสั่งนี้

เริ่มต้น: MOV AH, 02 ชม– บรรทัดที่ 4. ป้ายกำกับเริ่มต้นจะอยู่หน้าคำสั่งแรกในโปรแกรม และจะถูกใช้ในคำสั่ง END เพื่อระบุว่าโปรแกรมเริ่มต้นด้วยคำสั่งใด คำสั่ง MOV จะใส่ค่าของตัวถูกดำเนินการตัวที่สองลงในตัวถูกดำเนินการตัวแรก นั่นคือค่า 02h จะถูกวางไว้ในรีจิสเตอร์ AN เหตุใดจึงทำเช่นนี้? 02h เป็นฟังก์ชัน DOS ที่แสดงอักขระบนหน้าจอ เรากำลังเขียนโปรแกรมสำหรับ DOS ดังนั้นเราจึงใช้คำสั่งนี้ ระบบปฏิบัติการ(ระบบปฏิบัติการ) และเราเขียนฟังก์ชันนี้ (หรือแทนที่จะเป็นตัวเลข) ในรีจิสเตอร์ AH เนื่องจากอินเทอร์รัปต์ 21h ใช้รีจิสเตอร์นี้

MOV DL, 41 ชม– บรรทัดที่ 5. รหัสอักขระ "A" ถูกป้อนลงในรีจิสเตอร์ DL รหัส ASCII สำหรับอักขระ "A" คือ 41h

อินท์ 21ชม– บรรทัดที่ 6. นี่คือการขัดจังหวะ 21 ชั่วโมงเดียวกัน - คำสั่งที่ทำให้เกิด ฟังก์ชั่นระบบ DOS ที่ระบุใน AN register (ในตัวอย่างของเราคือฟังก์ชัน 02h) คำสั่ง INT 21h เป็นวิธีหลักในการโต้ตอบระหว่างโปรแกรมและระบบปฏิบัติการ

อินท์ 20ชม– บรรทัดที่ 7. นี่คือการขัดจังหวะที่บอกให้ระบบปฏิบัติการออกจากโปรแกรมและถ่ายโอนการควบคุมไปยังแอปพลิเคชันคอนโซล หากโปรแกรมได้รับการคอมไพล์และเปิดใช้งานจากระบบปฏิบัติการแล้ว คำสั่ง INT 20h จะส่งคืนเราไปยังระบบปฏิบัติการ (เช่น ไปยัง DOS)

สิ้นสุด เริ่มต้น– บรรทัดที่ 8. คำสั่ง END สิ้นสุดโปรแกรมโดยระบุว่าควรเริ่มดำเนินการที่จุดใด

Directives คือคำสั่งควบคุมคอมไพเลอร์ คำประกาศของแต่ละคนต้องเริ่มต้นด้วยจุด การปฏิบัติแสดงให้เห็นว่าในแอสเซมเบลอร์ใดๆ มีเพียงประมาณ 10...20 คำสั่งเท่านั้นที่ถูกใช้งานอย่างเข้มข้นที่สุด คุณสมบัติอื่นๆ ทั้งหมดเป็นทางเลือกหรือรับผิดชอบในการควบคุมคุณสมบัติคอมไพเลอร์รองเท่านั้น คำสั่ง “พื้นฐาน” ซึ่งเป็นเรื่องปกติสำหรับแอสเซมบลีของโปรเซสเซอร์อื่นๆ รวมถึงคำสั่ง .equ, .org, .def, .сseg, .dseg ฯลฯ คำสั่งเช่น .dq, .exit, .listmac in โปรแกรมจริงหายากมากจริงๆ ด้านล่างนี้คือรายการ คำอธิบาย และตัวอย่างการใช้คำสั่งจากแอสเซมเบลอร์ที่เป็นกรรมสิทธิ์ของไมโครคอนโทรลเลอร์ AVR

การทดแทนคำสั่ง .include ไฟล์ข้อความไปยังตำแหน่งในโปรแกรมที่ใช้งาน นอกจากนี้ ไฟล์ทดแทนอาจมีคำสั่ง .include อีกด้วย หากไฟล์อยู่ในไดเร็กทอรีโครงการหรือในโฟลเดอร์บริการใดโฟลเดอร์หนึ่ง เส้นทางเต็มอนุญาตให้ระบุเฉพาะลิงก์ไปยังชื่อของเขาเท่านั้น

Directive.include
การเขียนไวยากรณ์:
.include "(เส้นทางไฟล์)"
ตัวอย่างการใช้งาน:

รวม "m8def.inc" ; ใส่ไฟล์ส่วนหัวมาตรฐาน

คำสั่ง .exit จะบอกแอสเซมเบลอร์ว่าไฟล์สิ้นสุดที่ใด ข้อความต้นฉบับ- คำสั่งทั้งหมดหลังจากคำสั่งจะไม่ปรากฏแก่คอมไพเลอร์ หาก .exit เกิดขึ้นในไฟล์ที่รวมไว้ การสร้างโปรเจ็กต์จะสิ้นสุดด้วยบรรทัดที่มีคำสั่ง .include อยู่ หากไม่มีคำสั่ง .exit ระบบจะพิจารณาจุดสิ้นสุดของบิลด์ บรรทัดสุดท้ายข้อความต้นฉบับ

คำสั่งทางออก
การเขียนไวยากรณ์:
.ออก
ตัวอย่างการใช้งาน:

ออก ;สิ้นสุดไฟล์

คำสั่ง .nolist และ .list ควบคุมไฟล์รายการ ซึ่งโดยปกติจะถูกสร้างขึ้นหลังจากสร้างโปรเจ็กต์แล้ว ประการแรกห้ามและอีกประการหนึ่งจึงอนุญาตให้ส่งออกข้อมูลไปยังไฟล์ได้ คำสั่ง .list จะแทนที่การกระทำของ .nolist และในทางกลับกัน

คำสั่ง nolist, .list
การเขียนไวยากรณ์:
.nolist, .รายการ
ตัวอย่างการใช้งาน:

Nolist ;ห้ามส่งออกข้อความของไฟล์ “m8def.inc” .รวม "m8def.inc" ;ลงในรายการโปรแกรม file.list ;ส่งออกข้อมูลต่อไป

คำสั่ง .equ กำหนดชื่อเชิงสัญลักษณ์ให้กับบางคน ค่าตัวเลข- ชื่อสัญลักษณ์จะต้องไม่ซ้ำกันและไม่สามารถเปลี่ยนแปลงได้ในขณะที่กำลังเขียนโปรแกรม ไม่สามารถใช้คำสั่งเพื่อกำหนดชื่อเชิงสัญลักษณ์ให้กับรีจิสเตอร์ได้ จุดประสงค์ทั่วไป.

คำสั่ง.equ
การเขียนไวยากรณ์:
.equ (ชื่อสัญลักษณ์) = (นิพจน์)
ตัวอย่างการใช้งาน:

Equ DDRB = 0x17 ;ตั้งชื่อ DDRB เป็น 0x17 .equ PORTB = DDRB + 1 ;ตั้งชื่อ PORTB เป็น 0x18

คำสั่ง .set มีผลเช่นเดียวกับ .equ แต่ต่างจากอย่างหลังตรงที่ชื่อเชิงสัญลักษณ์สามารถกำหนดใหม่ได้ทุกที่ในโปรแกรม

คำสั่ง.set
การเขียนไวยากรณ์:
.set (ชื่อสัญลักษณ์) = (นิพจน์)
ตัวอย่างการใช้งาน:

ตั้งค่า OFFSET = 0x100 กำหนดชื่อ ค่าออฟเซ็ต 0x100 . .set OFFSET = OFFSET + 1 แทนที่ค่า OFFSET

คำสั่ง .def กำหนดชื่อเชิงสัญลักษณ์ให้กับหนึ่งในการลงทะเบียนวัตถุประสงค์ทั่วไป ในหลักสูตรต่อไปของโปรแกรม ชื่อที่กำหนดสามารถแทนที่ได้ด้วยคำสั่ง .undef

คำสั่ง .def, .undef
การเขียนไวยากรณ์:
.def (ชื่อสัญลักษณ์) = (ตัวพิมพ์)
.undef (ชื่อเชิงสัญลักษณ์)
ตัวอย่างการใช้งาน:

Def temp = R16 ; กำหนด register R16 ชื่อ temp .undef temp ; ยกเลิกการใช้ชื่อ temp ต่อไป

คำสั่ง .db, .dw, .dd, .dq มีวัตถุประสงค์เพื่อสำรองหน่วยความจำไมโครคอนโทรลเลอร์สำหรับข้อมูลที่เตรียมใช้งาน ทั้งหมดสามารถใช้ได้เฉพาะในส่วนของโค้ดและหน่วยความจำ EEPROM เท่านั้น ความแตกต่างระหว่างคำสั่งเหล่านี้คือความลึกของบิตของข้อมูลที่แสดง คำสั่ง .db จะสงวนไบต์, .dw จะสงวนคำ, .dd จะสงวนคำคู่ ในบางกรณีที่พบไม่บ่อย การใช้คำสั่ง .dq ซึ่งสงวนข้อมูล 64 บิตอาจสะดวกกว่า

คำสั่ง.db, .dw, .dd, .dq
การเขียนไวยากรณ์:
(ป้ายกำกับ): .db (ข้อมูล 8 บิต)
(ป้ายกำกับ): .dw (ข้อมูล 16 บิต)
(ป้ายกำกับ): .dd (ข้อมูล 32 บิต)
(ป้ายกำกับ): .dq (ข้อมูล 64 บิต)
ตัวอย่างการใช้งาน:

ป้ายกำกับ: .db 0xFA, 250, -6, 0b11111010 .dw 0xFADE, 64222, -1314, 0b1111101011011110 .dd 0xFADEEFCA, 4208914378, -86052918 .dq 0xFADEEFCAEFBACDEF, 8077149609196178927, -521103510453211

คำสั่ง .byte สงวนหน่วยความจำสำหรับข้อมูลที่ยังไม่ได้เตรียมใช้งานในส่วน SRAM และ EEPROM

คำสั่ง.ไบต์
การเขียนไวยากรณ์:
(ป้ายกำกับ): .byte (จำนวนข้อมูลที่จะสำรอง)
ตัวอย่างการใช้งาน:

เท่ากับ PAGESIZE = 0x20 บัฟเฟอร์: . ไบต์ 2*PAGESIZE สำรอง 64 ไบต์ใน SRAM

คำสั่ง .dseg, .eseg, .cseg กำหนดจุดเริ่มต้นของข้อมูล, EEPROM และส่วนของโค้ด ตามลำดับ ใน ไฟล์ต้นฉบับแต่ละส่วนสามารถแสดงได้ในสำเนาเดียวเท่านั้น หากคำสั่งเหล่านี้หายไปในโปรแกรม คอมไพลเลอร์โดยค่าเริ่มต้นจะถือว่าคำสั่งทั้งหมดอยู่ในส่วนของรหัส

คำสั่ง .dseg, .eseg, .cseg
การเขียนไวยากรณ์:
.dseg
.eseg
.ซีซีจี
ตัวอย่างการใช้งาน:

Dseg ; จุดเริ่มต้นของบัฟเฟอร์ส่วนข้อมูล: . ไบต์ 32 ; สำรอง 32 ไบต์สำหรับบัฟเฟอร์ใน SRAM .cseg ; จุดเริ่มต้นของส่วนโค้ด rjmp เริ่มต้น string: .db "ATmega8",0 ;string เก็บไว้ในหน่วยความจำ FLASH.eseg ;จุดเริ่มต้นของส่วนหน่วยความจำ EEPROM _var: .byte 2 ;สำรอง 2 ไบต์สำหรับตัวแปร _var _cnst: .db 0xAA ;สำรองไบต์สำหรับตัวแปร _cnst = 0xAA

คำสั่ง The.org ช่วยให้คุณสามารถตั้งค่าที่อยู่เริ่มต้นของคอมไพลเลอร์ภายในโค้ด ข้อมูล และเซ็กเมนต์ EEPROM เมื่อใช้ในส่วนโค้ด คำสั่งจะระบุที่อยู่ตำแหน่งของคำโปรแกรม 16 บิต

ไดเรกทีฟ.org
การเขียนไวยากรณ์:
.org (ที่อยู่เริ่มต้น)
ตัวอย่างการใช้งาน:

Equ SRAM_START = 0x60 .equ RAMEND = 0x045F .dseg ;จุดเริ่มต้นของข้อมูล Segment.org SRAM_START ;สำรอง 32 ไบต์ใน SRAM สำหรับบัฟเฟอร์ บัฟเฟอร์: ไบต์ 32; เริ่มต้นที่ที่อยู่ 0x60 .cseg; เริ่มต้นของรหัสเซกเมนต์.org 0; รีเซ็ตเวกเตอร์ที่ที่อยู่ 0 rjmp เริ่มต้น .org 0x50 ;เริ่มโปรแกรมหลักที่ที่อยู่ 0x50 เริ่มต้น: ldi temp,สูง(RAMEND) ;การเริ่มต้นสแต็กออก SPH,temp ldi temp,ต่ำ(RAMEND) ออก SPL,temp

คำสั่ง .macro, .endmacro (.endm) กำหนดจุดเริ่มต้นและจุดสิ้นสุดของแมโครตามลำดับ

Directives.macro, .endmacro (.endm)
การเขียนไวยากรณ์:
.มาโคร (ชื่อมาโคร)
ตัวอย่างการใช้งาน:

Macro set_bit ;การประกาศแมโครสำหรับการตั้งค่าบิตพอร์ต sbi @0,@1 ;set bit @1 ของพอร์ต register @0 sbi @0-1,@1 ;กำหนดค่าบรรทัด @1 ของ DDRx register .endm สำหรับเอาต์พุต . set_bit PORTB,0 ; ตั้งค่าตรรกะพอร์ต B 1 บนบรรทัด 0

คำสั่ง .listmac อนุญาตให้แสดงข้อความแมโครเพิ่มเติมในไฟล์รายการ ในกรณีนี้ เนื้อหาของแต่ละคำจำกัดความของแมโครที่พบในโปรแกรมจะแสดงอย่างครบถ้วน หากไม่ได้ใช้คำสั่ง จะไม่มีการกำหนดโค้ดภายในมาโคร

คำสั่ง.listmac
การเขียนไวยากรณ์:
.listmac
ตัวอย่างการใช้งาน:

Listmac อนุญาตให้ขยายข้อความมาโครในไฟล์รายการ

คำสั่ง .message, .warning, .error มีวัตถุประสงค์เพื่อส่งออกไปยังหน้าต่างการสร้างโครงการ ข้อมูลเพิ่มเติมเกี่ยวกับความคืบหน้าการเรียบเรียงโปรแกรม คำสั่ง .message จะสร้างข้อความสำหรับบรรทัดที่พบการโทร การใช้ .warning ส่งผลให้เกิดคำเตือน และ .error ส่งผลให้เกิดข้อความแสดงข้อผิดพลาด ในกรณีหลัง การสร้างโครงการจะหยุดลง

คำสั่ง .message, .warning, .error
การเขียนไวยากรณ์:
.message "(ข้อความ)"
.warning "(ข้อความเตือน)"
.error "(ข้อความแสดงข้อผิดพลาด)"
ตัวอย่างการใช้งาน:

ข้อความ "มาโครถูกเรียกที่นี่" .warning "ความถี่สูงเกินไป!" .error "อาร์กิวเมนต์แมโครผิด!"

กลุ่มของคำสั่งการคอมไพล์แบบมีเงื่อนไข ifdef, .ifndef, .if, .else, elif, .endif ถูกนำมาใช้สำหรับการแทรก รหัสโปรแกรมขึ้นอยู่กับ เงื่อนไขต่างๆ- คำสั่ง .ifdef จะตรวจสอบการมีอยู่ของการประกาศชื่อเชิงสัญลักษณ์หรือไม่ คำสั่งสามารถตามด้วยชุดคำสั่งที่จะแทรกลงในข้อความหากเงื่อนไขการทดสอบเป็น "จริง" (ชื่อได้รับการประกาศ) คำสั่ง .ifndef ตรงกันข้ามกับ .ifdef ซึ่งจะตรวจสอบว่าไม่มีการประกาศชื่อเชิงสัญลักษณ์หรือไม่ คำสั่ง .if ดำเนินการทดแทนโค้ดเมื่อตรงตามเงื่อนไขการเปรียบเทียบที่ระบุเป็นพารามิเตอร์ คำสั่งที่ต้องดำเนินการหากเงื่อนไขของคำสั่ง .if เป็น “false” จะอยู่หลังคำสั่ง .else การแตกแขนงเช่น "if" - "then" สามารถมีการซ้อนได้หลายระดับด้วยคำสั่ง .elif ทุกบล็อคตรวจสอบที่ขึ้นต้นด้วย .ifdef, .ifndef, .if จะต้องปิดด้วยคำสั่ง .endif

คำสั่ง if, .ifdef, .ifndef, .else, elif, .endif
การเขียนไวยากรณ์:
.ifdef (อักขระ) (หรือ .ifndef (อักขระ))
.if (เงื่อนไข)
.else (นิพจน์) (หรือ .elif (เงื่อนไข))
.endif
ตัวอย่างการใช้งาน:

Macro del_ms ;มาโครที่สร้างการหน่วงเวลาใน ms.ifndef FREQ ;หากไม่ได้ประกาศค่าคงที่ FREQ (ความถี่เป็น Hz) .warning "ค่าคงที่ FREQ ที่ไม่ได้กำหนด!" ;ออกคำเตือน และ.equ FREQ = 1000000 ;กำหนดค่าเริ่มต้นเป็น 1 MHz.endif .equ DELAY = (@0*FREQ)/4000 ;ค่าการตั้งค่าการหน่วงเวลาหาก DELAY > 65535 ;หาก DELAY มากกว่า 2 ไบต์ จากนั้นเกิดข้อผิดพลาด “จำนวนเต็มล้นใน DELAY!” ;ไม่สามารถใช้งานมาโครได้ มิฉะนั้นให้กด XL ;บันทึกการลงทะเบียนการทำงาน XL, XH กด XH ldi XH,สูง(DELAY) ;รอบการหน่วงเวลา ldi XL,ต่ำ(DELAY) sbiw XH:XL,1 brne PC-1 pop XH pop XL ;คืนค่าการลงทะเบียนการทำงาน XH, XL จากสแต็ก .endif .endm .equ FREQ = 2000000 ;โฆษณา ความถี่สัญญาณนาฬิกา 2 เมกะเฮิรตซ์ del_ms 25 ; การหน่วงเวลา 25 ms

ภาษาการเขียนโปรแกรมแอสเซมบลีจะรวมอยู่เสมอ รหัสเครื่องไมโครคอนโทรลเลอร์ แต่ไม่จำกัดเพียงชุดคำสั่งของภาษานี้ ประเด็นก็คือคุณจะต้องสามารถจัดการกระบวนการออกอากาศรายการได้ด้วยตัวเอง รายการคำสั่งทั้งหมดมีอยู่ในคำอธิบายภาษา และบางส่วนจะมีการพูดคุยโดยละเอียดที่นี่

สิ่งแรกที่ไม่สะดวกเมื่อใช้คำสั่งเครื่องเพียงอย่างเดียวคือต้องจำไว้ว่าข้อมูลใดอยู่ในเซลล์หน่วยความจำใด เมื่ออ่านโปรแกรม เป็นการยากที่จะแยกแยะค่าคงที่จากตัวแปร เนื่องจากจะแตกต่างกันในคำสั่งตามประเภทของการกำหนดแอดเดรสเท่านั้น ความยากลำบากนี้สามารถเอาชนะได้โดยใช้ตัวระบุ คุณสามารถกำหนดตัวระบุให้กับเซลล์หน่วยความจำใดก็ได้ และด้วยเหตุนี้จึงทำงานกับตัวระบุนี้เป็นตัวแปรได้

คำสั่งเทียบเท่าช่วยให้คุณสามารถกำหนดชื่อให้กับตัวแปรและค่าคงที่ได้ ตอนนี้คุณสามารถกำหนดที่อยู่ให้กับตัวแปรได้ในที่เดียว และใช้ตัวระบุตัวแปรทั่วทั้งโปรแกรม จริงอยู่ที่โปรแกรมเมอร์มีหน้าที่ในการใช้ตัวระบุเป็นตัวแปรอย่างไรก็ตามหากในกระบวนการเขียนโปรแกรมจำเป็นต้องเปลี่ยนที่อยู่ของตัวแปรก็สามารถทำได้ในที่เดียวในโปรแกรมแทนที่จะผ่าน โปรแกรมทั้งหมด ค้นหาว่าตัวเลข 10 เป็นค่าคงที่ในคำสั่งนี้ ที่อยู่ของเซลล์ หรือจำนวนการซ้ำในรอบ การเปลี่ยนแปลงที่จำเป็นทั้งหมดจะดำเนินการโดยนักแปลเอง ตัวอย่างการกำหนดตัวแปรมีให้ไว้ในตัวอย่างที่แสดงในรายการ 1


รายการ 1. การกำหนดตัวแปรโดยใช้คำสั่ง Equi

ดังที่เห็นในตัวอย่างด้านบน การใช้ตัวระบุช่วยเพิ่มความเข้าใจของโปรแกรมได้อย่างมาก เนื่องจากชื่อของตัวแปรจะแสดงฟังก์ชันที่ตัวแปรนี้รับผิดชอบ

เมื่อใช้คำสั่ง Equi คุณสามารถกำหนดไม่เพียงแต่ตัวแปร แต่ยังรวมถึงค่าคงที่ด้วย ตามที่กล่าวไว้ข้างต้น ไม่ว่าตัวระบุจะถูกใช้เป็นตัวแปรหรือเป็นค่าคงที่ ขึ้นอยู่กับคำสั่งและประเภทของการกำหนดแอดเดรสที่โปรแกรมเมอร์ใช้

เมื่อกำหนดตัวระบุแล้ว จะไม่สามารถเปลี่ยนแปลงได้ในอนาคต และหากคุณพยายามกำหนดชื่อตัวระบุที่เหมือนกันทุกประการอีกครั้ง ข้อความแสดงข้อผิดพลาดจะปรากฏขึ้น

กำหนดคำสั่ง- หากคุณต้องการกำหนดหมายเลขที่แตกต่างกันให้กับตัวระบุเดียวกันในตำแหน่งที่แตกต่างกันในโปรแกรม คุณจะต้องใช้คำสั่งที่ตั้งไว้ การใช้คำสั่งนี้เหมือนกับการใช้คำสั่ง Equi โดยสิ้นเชิง ดังนั้นจึงจะไม่แสดงตัวอย่างไว้ด้วย

ค่าคงที่ที่กำหนดโดยคำสั่ง Equi สามารถใช้ได้ในคำสั่งเดียวเท่านั้น บ่อยครั้งที่จำเป็นต้องทำงานกับตารางค่าคงที่ เช่น ตารางการแปลง ตารางฟังก์ชันพื้นฐาน หรือกลุ่มอาการของรหัสแก้ไขข้อผิดพลาด ค่าคงที่ดังกล่าวไม่ได้ใช้ในขั้นตอนการแปล แต่จะถูกเก็บไว้ในหน่วยความจำโปรแกรมไมโครคอนโทรลเลอร์ ในการป้อนค่าคงที่ลงในหน่วยความจำโปรแกรมไมโครคอนโทรลเลอร์ จะใช้คำสั่ง db และ dw

คำสั่ง dbใช้เพื่อจัดเก็บค่าคงที่ไบต์เดียวในหน่วยความจำโปรแกรม ตัวอย่างของการใช้คำสั่ง db แสดงอยู่ในรายการ 2


รายการ 2 การกำหนดค่าคงที่โดยใช้คำสั่ง db

ตัวอย่างนี้ใช้รูทีนย่อยของฟังก์ชันที่แปลงเลขทศนิยมไบนารีเป็นโค้ดเจ็ดส่วน รหัสทศนิยมไบนารี่จะถูกส่งไปยังฟังก์ชันนี้ผ่านทางตัวสะสม และรหัสเจ็ดส่วนจะถูกส่งกลับผ่านการลงทะเบียนเดียวกันไปยังโปรแกรมที่เรียก

ในคำสั่ง db คุณสามารถระบุค่าคงที่หลายรายการพร้อมกัน โดยคั่นด้วยเครื่องหมายจุลภาค คุณสามารถใช้ทั้งหมดพร้อมกันได้ แต่โดยทั่วไปแล้ว ควรระบุค่าคงที่แต่ละรายการพร้อมข้อคิดเห็น ดังที่ทำในตัวอย่างก่อนหน้านี้ วิธีนี้ทำให้โปรแกรมเข้าใจได้ง่ายขึ้นและค้นหาข้อผิดพลาดได้ง่ายขึ้น

คำสั่งเดียวกันทำให้ง่ายต่อการจดคำจารึกซึ่งจะต้องแสดงในภายหลังบนจอแสดงผลในตัวหรือหน้าจอแสดงผล คอมพิวเตอร์สากลเชื่อมต่อกับอุปกรณ์ที่กำลังพัฒนาผ่านอินเทอร์เฟซบางส่วน ตัวอย่างของการใช้คำสั่ง db เพื่อป้อนคำจารึกลงในหน่วยความจำโปรแกรมไมโครคอนโทรลเลอร์แสดงในรูปที่ 3

รูปที่ 3 การใช้คำสั่ง db เพื่อเขียนคำจารึกลงในหน่วยความจำโปรแกรมไมโครคอนโทรลเลอร์

คำสั่ง DWช่วยให้คุณจัดเก็บตัวเลขสองไบต์ลงในหน่วยความจำโปรแกรม ในคำสั่งนี้ เช่นเดียวกับในคำสั่ง db คุณสามารถป้อนตัวเลขโดยคั่นด้วยเครื่องหมายจุลภาค ตัวอย่างรายการส่วนของโปรแกรมแสดงในรูปที่ 4

รูปที่ 4 การใช้คำสั่ง dw

รูปที่ 4 แสดงส่วนของรายการโปรแกรมเพื่อให้คุณสามารถติดตามได้ว่าไบต์ใดถูกป้อนลงในหน่วยความจำโปรแกรมไมโครคอนโทรลเลอร์ ในส่วนใหญ่ คอลัมน์ด้านขวารายการแสดงที่อยู่ที่จะป้อนตัวเลขที่เป็นตัวถูกดำเนินการของคำสั่ง dw คอลัมน์ถัดไปแสดงตัวเลขสองไบต์ที่จะจัดเก็บไว้ในหน่วยความจำโปรแกรมไมโครคอนโทรลเลอร์ โปรดทราบว่าแม้ว่าตัวถูกดำเนินการสองตัวแรกจะมีเพียงตัวเลขเดียว แต่เลขฐานสิบหกสี่หลัก (ตัวเลขสองไบต์) จะถูกเก็บไว้ในหน่วยความจำของไมโครคอนโทรลเลอร์

เมื่อแปลข้อความต้นฉบับของโปรแกรม จะถือว่าคำสั่งแรกอยู่ที่ที่อยู่ศูนย์ ที่อยู่ของคำสั่งที่ตามมาจะขึ้นอยู่กับความยาวและจำนวนคำสั่งก่อนหน้า รายการตัวอย่างของส่วนเริ่มต้นของโปรแกรมแสดงในรูปที่ 5

รูปที่ 5. ตัวอย่างรายการโปรแกรม

บางครั้งคุณต้องจัดเรียงคำสั่งตาม ที่อยู่เฉพาะ- สิ่งนี้จำเป็นบ่อยที่สุดเมื่อใช้การขัดจังหวะ เมื่อคำสั่งแรกของโปรแกรมตัวจัดการการขัดจังหวะต้องอยู่บนเวกเตอร์ขัดจังหวะทุกประการ ซึ่งสามารถทำได้โดยใช้คำสั่ง nop เพื่อเติมช่องว่างระหว่างเวกเตอร์ขัดจังหวะ แต่จะเป็นการดีกว่าถ้าใช้คำสั่ง ORG

คำสั่งขององค์กร มีวัตถุประสงค์เพื่อเขียนค่าของตัวถูกดำเนินการไปยังตัวนับที่อยู่ส่วน นั่นคือเมื่อใช้คำสั่งนี้ คุณสามารถวางคำสั่ง (หรือข้อมูล) ในหน่วยความจำไมโครคอนโทรลเลอร์ตามที่อยู่ใดก็ได้ ตัวอย่างของการใช้คำสั่ง ORG เพื่อวางรูทีนขัดจังหวะบนเวกเตอร์ขัดจังหวะแสดงไว้ในรูปที่ 6

รูปที่ 6 ตัวอย่างการใช้คำสั่ง ORG

ควรสังเกตว่าเมื่อใช้คำสั่งนี้สถานการณ์อาจเกิดขึ้นได้เมื่อโปรแกรมเมอร์สั่งให้นักแปลวาง รหัสใหม่โปรแกรมในตำแหน่งที่เขียนไว้แล้ว ดังนั้นการใช้คำสั่งนี้จึงได้รับอนุญาตเฉพาะในเท่านั้น กรณีที่รุนแรง- โดยทั่วไปนี่คือการใช้เวกเตอร์ขัดจังหวะ

โดยใช้คำสั่ง เมื่อใช้การขัดจังหวะ เวลาที่โปรแกรมจัดการขัดจังหวะถือเป็นสิ่งสำคัญ เวลานี้สามารถลดลงได้อย่างมากโดยการจัดสรรธนาคารที่ลงทะเบียนแยกต่างหากสำหรับการประมวลผลขัดจังหวะ คุณสามารถเลือกธนาคารลงทะเบียนแยกต่างหากได้โดยใช้คำสั่ง USING หมายเลขธนาคารของการลงทะเบียนที่ใช้จะถูกระบุในคำสั่งว่าเป็นตัวถูกดำเนินการ ตัวอย่างของการใช้คำสั่ง USING สำหรับรูทีนบริการขัดจังหวะจากตัวจับเวลา 0 แสดงในรูปที่ 7

รูปที่ 7 ตัวอย่างการใช้คำสั่ง USING

คำสั่ง CALLระบบคำสั่งไมโครคอนโทรลเลอร์ MCS-51 ใช้คำสั่งข้ามแบบไม่มีเงื่อนไขสามคำสั่ง การเลือกคำสั่งเฉพาะนั้นขึ้นอยู่กับตำแหน่งในหน่วยความจำโปรแกรม แต่โดยปกติโปรแกรมเมอร์จะไม่ทราบเรื่องนี้ ด้วยเหตุนี้ เพื่อหลีกเลี่ยงข้อผิดพลาด คุณต้องใช้คำสั่ง LJMP ที่ยาวที่สุด สิ่งนี้นำไปสู่มากขึ้น โปรแกรมที่ยาวนานและเพื่อโหลดเพิ่มเติมในตัวแก้ไขลิงก์ นักแปลสามารถเลือกได้ ตัวเลือกที่ดีที่สุดคำสั่งกระโดดแบบไม่มีเงื่อนไข ในการดำเนินการนี้ แทนที่จะใช้คำสั่งไมโครคอนโทรลเลอร์ คุณควรใช้คำสั่งการโทร

คำสั่งที่เหลือมีวัตถุประสงค์เพื่อควบคุมส่วนต่างๆ และจะมีการหารือในภายหลังเมื่อหารือเกี่ยวกับการทำงานกับโปรแกรมหลายโมดูล

วรรณกรรม:

พร้อมกับอ่านบทความ "คำสั่งภาษาการเขียนโปรแกรม ASM-51":


http://site/Progr/progr.php

เมื่อเขียนโปรแกรมในภาษาแอสเซมบลีจะใช้คำสั่งที่ระบุตำแหน่งของโปรแกรมในหน่วยความจำให้คอมไพเลอร์กำหนดมาโครเริ่มต้นหน่วยความจำ ฯลฯ รายการคำสั่งและคำอธิบายมีอยู่ในตาราง 1.8. คำสั่งทั้งหมดเริ่มต้นด้วยจุด ให้เราแสดงรายการฟังก์ชันที่ดำเนินการโดยคำสั่งในแต่ละส่วนโดยย่อ

ส่วนของโปรแกรมจะเปิดขึ้นพร้อมกับคำสั่ง .CSEG หากโปรแกรมเริ่มต้นด้วยส่วนนี้ คำสั่งอาจหายไป ในส่วนของโปรแกรม คุณสามารถใช้คำสั่ง .ORG เพื่อระบุจุดเริ่มต้นของส่วนได้

คำสั่ง .DB ในส่วนกำหนดหนึ่งไบต์หรือกลุ่มของไบต์ของค่าคงที่ที่เขียนลงในหน่วยความจำแฟลช คำสั่ง .DW กำหนดคำหรือกลุ่มของคำที่เขียนลงในหน่วยความจำเป็นค่าคงที่ จุดเริ่มต้นของการบันทึกค่าคงที่ถูกกำหนดโดยป้ายกำกับที่อยู่ก่อนหน้าคำสั่งที่เกี่ยวข้อง ค่าคงที่ที่ระบุจะถูกคั่นด้วยเครื่องหมายจุลภาค

คำสั่ง .DEF กำหนดชื่อเชิงสัญลักษณ์ให้กับรีจิสเตอร์ คำสั่ง .EQU, .SET กำหนดค่าให้กับชื่อ ชื่อที่กำหนดค่าตามคำสั่ง .EQU ไม่สามารถกำหนดใหม่ได้ และค่าไม่สามารถเปลี่ยนแปลงได้ ชื่อที่กำหนดโดยคำสั่ง .SET สามารถเปลี่ยนแปลงได้ด้วยคำสั่ง .SET อื่น

คำสั่ง .DEVICE ระบุประเภทของไมโครคอนโทรลเลอร์เป้าหมายที่จะใช้ในการรันโปรแกรม การมีอยู่ของคำสั่งนี้ทำให้สามารถติดตามคำสั่งของโปรแกรมที่เกี่ยวข้องได้ อุปกรณ์ทางกายภาพ, คำเตือนเกี่ยวกับความเป็นไปไม่ได้ในการดำเนินการตามคำสั่งบางอย่าง, ขนาดของหน่วยความจำที่ใช้ ฯลฯ

คำสั่ง .INCLUDE พร้อมชื่อไฟล์ใช้เพื่อรวมไฟล์อื่นในข้อความของโปรแกรม

ตารางที่ 1.8. รายการคำสั่ง

คำสั่ง

คำอธิบาย

สำรองไบต์ใน RAM

ส่วนโปรแกรม

กำหนดไบต์ - ค่าคงที่ในหน่วยความจำแฟลชหรือ

กำหนดชื่อเชิงสัญลักษณ์ให้กับรีจิสเตอร์

ระบุอุปกรณ์ที่จะคอมไพล์

โปรแกรม

ส่วนข้อมูล

กำหนดคำในหน่วยความจำแฟลชหรือ EEPROM

จุดสิ้นสุดของมาโคร

ตั้งค่านิพจน์คงที่

ส่วน EEPROM

ออกจากไฟล์

แนบไฟล์อื่น

เปิดใช้งานการสร้างรายการ

เปิดใช้งานการขยายมาโครในรายการ

จุดเริ่มต้นของมาโคร

ปิดการสร้างรายการ

กำหนดตำแหน่งในส่วน

ตั้งค่าตัวแปรให้เป็นนิพจน์ที่เทียบเท่า

คำสั่ง .MACRO และ .ENDMACRO กำหนดกรอบคำจำกัดความของแมโคร คำจำกัดความของแมโครสามารถมีพารามิเตอร์ได้สูงสุด 10 ตัว ชื่อคงที่@0,…,@9. เมื่อเรียกคำนิยามแมโคร พารามิเตอร์จะถูกระบุเป็นรายการตามลำดับตัวเลข

ส่วนข้อมูลเริ่มต้นด้วยคำสั่ง .DSEG คำสั่ง .ORG และ .BYTE สามารถใช้ในกลุ่มได้ คำสั่ง .BYTE ระบุจำนวนไบต์ที่จะเข้าถึงระหว่างการทำงานของโปรแกรม พื้นที่สงวนเริ่มต้นจากที่อยู่ที่ระบุโดยป้ายกำกับก่อนคำสั่ง

ส่วนประเภท EEPROM เริ่มต้นด้วยคำสั่ง .ESEG สามารถใช้คำสั่ง .ORG, .DB, .DW ได้ในเซ็กเมนต์ คำสั่ง .DB ในส่วนระบุหนึ่งหรือกลุ่มของไบต์ที่จะเขียนลงใน EEPROM คำสั่ง DW กำหนดคำหรือกลุ่มคำที่เขียนลงในหน่วยความจำ EEPROM เป็นคู่ละ 2 ไบต์ จุดเริ่มต้นของการบันทึกไบต์และคำถูกกำหนดโดยป้ายกำกับที่อยู่หน้าคำสั่งที่เกี่ยวข้อง

คำสั่ง .LIST, .NOLIST, .LISTMAC ใช้เพื่อควบคุมเอาต์พุตของรายการ

แท็ก
ป้ายในภาษาแอสเซมบลีสามารถมีสัญลักษณ์ต่อไปนี้:


ตัวอักษร: A ถึง Z และ a ถึง z
ตัวเลข: 0 ถึง 9
ตัวอักษรพิเศษ: เครื่องหมายคำถาม (?)
จุด (.) (อักขระตัวแรกเท่านั้น)
ป้าย "เชิงพาณิชย์" (@)
ขีดเส้นใต้ (_)
ดอลลาร์ ($)

อักขระตัวแรกในป้ายกำกับต้องเป็นตัวอักษรหรืออักขระพิเศษ ตัวเลขไม่สามารถเป็นอักขระตัวแรกของป้ายกำกับ และอักขระ $ และ ? บางครั้งมีความหมายพิเศษ และโดยทั่วไปไม่แนะนำให้ใช้ ตัวอักษรตัวพิมพ์ใหญ่และตัวพิมพ์เล็กจะไม่แยกความแตกต่างตามค่าเริ่มต้น แต่สามารถเปิดใช้งานความแตกต่างได้โดยการตั้งค่าตัวเลือกหนึ่งหรือตัวเลือกอื่น บรรทัดคำสั่งผู้ประกอบ ความยาวสูงสุดแท็ก - 31 ตัวอักษร ตัวอย่างป้ายกำกับ: COUNT, PAGE25, $E10 ขอแนะนำให้ใช้ป้ายกำกับที่สื่อความหมายและความหมาย ชื่อรีจิสเตอร์ เช่น AX, DI หรือ AL จะถูกสงวนไว้ และใช้เพื่อระบุรีจิสเตอร์ที่เกี่ยวข้องเท่านั้น
หากป้ายกำกับอยู่ก่อนคำสั่งของตัวประมวลผล หลังจากนั้นจะมีสัญลักษณ์ “:” (โคลอน) เสมอ ซึ่งบอกให้แอสเซมเบลอร์สร้างตัวแปรด้วยชื่อนี้ซึ่งมีที่อยู่ของคำสั่งปัจจุบัน:
some_loop:

วนซ้ำ some_loop
เมื่อป้ายกำกับปรากฏขึ้นก่อนคำสั่งแอสเซมเบลอร์ มักจะเป็นหนึ่งในตัวถูกดำเนินการของคำสั่งนั้น และจะไม่รวมเครื่องหมายทวิภาค:

ส่วนรหัส
ลอดสว ; อ่านคำจากสตริง
ขวานซีเอ็มพี,7 ; ถ้าเป็น 7 - ออกจากลูป
รหัสสิ้นสุด
มาดูคำสั่งที่ทำงานโดยตรงกับป้ายกำกับและค่าต่างๆ: LABEL, EQU และ =

คำสั่งฉลาก

ประเภทฉลาก คำสั่ง LABEL จะกำหนดฉลากและระบุประเภทของฉลาก ประเภทสามารถเป็นหนึ่งใน: BYTE (ไบต์), WORD (คำ), DWORD (คำคู่), FWORD (6 ไบต์), QWORD (คำสี่เหลี่ยม), TBYTE (10 ไบต์), NEAR (ใกล้ป้ายกำกับ), FAR (ไกล) ฉลาก ). ป้ายกำกับจะได้รับค่าเท่ากับที่อยู่ของคำสั่งถัดไปหรือข้อมูลถัดไป และประเภทที่ระบุอย่างชัดเจน ขึ้นอยู่กับประเภทของคำสั่ง
mov label,0 จะเขียนไบต์ (คำ, doubleword ฯลฯ) ที่เต็มไปด้วยเลขศูนย์ลงในหน่วยความจำ และคำสั่ง
ป้ายกำกับการโทรจะทำการโทรสั้นหรือยาวไปยังรูทีนย่อย

การใช้คำสั่ง LABEL จะสะดวกในการจัดการการเข้าถึงข้อมูลเดียวกัน ทั้งไบต์และคำ โดยการกำหนดป้ายกำกับสองป้ายที่มีประเภทต่างกันด้านหน้าข้อมูล

คำสั่ง EQU

คำสั่ง EQU จะกำหนดค่าให้กับป้ายกำกับ ซึ่งถูกกำหนดตามผลลัพธ์ของนิพจน์จำนวนเต็มทางด้านขวา ผลลัพธ์ของนิพจน์นี้อาจเป็นจำนวนเต็ม ที่อยู่ หรือสตริงอักขระใดๆ:
ฉลากเท่ากับการแสดงออก

ความจริงเท่ากับ 1
message1 เท่ากับ "ลองอีกครั้ง $"
var2 เท่ากับ 4
ขวาน cmp ความจริง ; ขวานซีเอ็มพี1
ฐานข้อมูลข้อความ1 ; db "ลองอีกครั้ง $"
ขวาน mov,var2 ; mov ax, 4 คำสั่ง EQU มักใช้เพื่อแนะนำพารามิเตอร์ทั่วไปสำหรับทั้งโปรแกรม คล้ายกับคำสั่ง #define ของตัวประมวลผลล่วงหน้า C

คำสั่ง =

คำสั่ง = เทียบเท่ากับ EQU แต่ป้ายกำกับที่กำหนดจะยอมรับได้เฉพาะค่าจำนวนเต็มเท่านั้น นอกจากนี้ ป้ายกำกับที่ระบุโดยคำสั่งนี้สามารถแทนที่ได้

แอสเซมเบลอร์แต่ละรายเสนอฉลากที่กำหนดไว้ล่วงหน้าพิเศษทั้งชุดซึ่งสามารถทำได้ วันที่ปัจจุบัน(@date หรือ ??date), ประเภทโปรเซสเซอร์ (@cpu) หรือชื่อของส่วนของโปรแกรมเฉพาะ แต่ป้ายกำกับที่กำหนดไว้ล่วงหน้าเพียงป้ายเดียวที่แอสเซมเบลอร์ทั้งหมดที่เราตรวจสอบคือ $ มันสอดคล้องกับที่อยู่ปัจจุบันเสมอ เช่น คำสั่ง

เจเอ็มพี$

ดำเนินการสาขาที่ไม่มีเงื่อนไขในตัวเอง ดังนั้นจึงสร้างลูปนิรันดร์จากคำสั่งเดียว

เพื่อให้เข้าใจเรื่องทั้งหมดนี้ได้ดีขึ้น ฉันจึงเขียนโปรแกรมขนาดเล็กขึ้นมา ยังคงเป็น “Hello World” เหมือนเดิม แต่ในรูปแบบใหม่ :) ข้อความด้านล่าง:

โปรแกรมถูกประกอบโดย TASM และ MASM แต่ไฟล์ EXE ที่ประกอบโดย MASM นั้นใหญ่กว่าหนึ่งไบต์ เราสังเกตเห็นว่าคำสั่ง mov dx,offset msg ถูกแทนที่ด้วยคำสั่ง lea dx,msgb LEA วางที่อยู่ออฟเซ็ตของข้อมูลที่ระบุใน DX เช่น ทำสิ่งเดียวกันกับคำสั่ง mov ที่มีออฟเซ็ต ฉันขอแนะนำให้ดูสิ่งนี้ภายใต้ดีบักเกอร์



ลองดูรายการประกอบอย่างละเอียดแล้วค้นหาความแตกต่าง



สิ่งที่น่าสนใจคือ TASM ได้รวบรวมคำสั่ง LEA ไว้ ในกรณีนี้เนื่องจากคำสั่ง MOV (opcode BA) และ MASM ได้รวบรวมคำสั่ง LEA ไว้ใน opcode อื่น - 8D16 ซึ่งเพิ่มขนาดโปรแกรมขึ้น 1 ไบต์ ฉันไม่รู้ว่าทำไมเขาถึงตัดสินใจทำเช่นนี้ แต่มันน่าสนใจที่จะค้นหา