การเขียนโปรแกรมด้วยรหัสเครื่องและภาษาแอสเซมบลี คำสั่งแอสเซมบลีพื้นฐาน

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


ตัวอักษร: 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 จะเขียนไบต์ (คำ สองคำ ฯลฯ) ที่เต็มไปด้วยเลขศูนย์ลงในหน่วยความจำ และคำสั่ง
ป้ายกำกับการโทรจะทำการโทรสั้นหรือยาวไปยังรูทีนย่อย

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

หนึ่งใน องค์ประกอบสำคัญหนังสือเล่มนี้ประกอบด้วยตัวอย่างโปรแกรมต่างๆ ค่ะ รหัสเครื่องและในภาษา ASSEMBLY ในการพิมพ์โปรแกรมเหล่านี้เราจะต้องใช้สิ่งนี้

เรียกว่า ASSEMBLY DIREECTIVES และตอนนี้น่าจะมากที่สุด เวลาที่สะดวกเพื่อให้เข้าใจว่ามันคืออะไร

เราจะดูคำสั่งต่อไปนี้: ORG, EQU, DEFB, DEFW, DEFM และ END แต่ก่อนที่เราจะเริ่มพิจารณาคำสั่งเหล่านี้ เราต้องเข้าใจให้แน่ชัดก่อน:

1. คำสั่ง ASSEMBLY ไม่ใช่คำสั่งของโปรเซสเซอร์ Z8 0 และในแง่นี้ไม่เกี่ยวข้องกับรหัสเครื่อง Z8 0

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

3. มีโปรแกรม ASSEMBLY มากมาย และแต่ละโปรแกรมสามารถมีแนวทางของตัวเองได้ อาจมีคำสั่งเดียวกัน แต่มีข้อกำหนดในการใช้งานที่แตกต่างกัน กล่าวอีกนัยหนึ่ง คุณต้องสร้างวิธีการเฉพาะสำหรับการใช้คำสั่ง ASSEMBLY ตามคำแนะนำสำหรับโปรแกรมแอสเซมบลีที่คุณใช้ (เช่น EDITAS, GENS 3, GENS 4, ZEUS เป็นต้น) และถึงแม้จะไม่มีมาตรฐาน แต่ก็ยังสามารถระบุแนวคิดพื้นฐานบางประการได้ และเราจะมุ่งเน้นไปที่แนวคิดเหล่านั้น

3.1. ความคิดเห็น

เราจะเริ่มต้นด้วยสิ่งที่ง่ายที่สุด - ความคิดเห็น เขียนไว้หลังสัญลักษณ์ ";" (อัฒภาค).

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

ตัวอย่างเช่น:

10 60001 แอลดี อี,เอ 2 0

อย่างที่คุณเห็นเส้นสามารถ

- โหลดลงในทะเบียน E ที่มี -; กดแบตเตอรี่ - ก็ลดลงไปหนึ่ง

เพียงจากความคิดเห็น

แท็ก

ป้ายกำกับทำให้การเขียนโปรแกรมช่วยจำ ASSEMBLY ง่ายขึ้นอย่างมาก ในการดำเนินการข้าม JP, JR, DJNZ และการเรียกรูทีนย่อย CALL คุณไม่สามารถระบุที่อยู่ที่คุณต้องการข้ามได้ แต่เปลี่ยนเลเบลแทน ในทางกลับกัน เมื่อคุณเขียนคำสั่งสำหรับที่อยู่นี้ ให้ใส่เครื่องหมายไว้ตรงนั้นด้วย ตัวอย่างเช่น

10 60001 เริ่มต้น LD B,0 4

20 60003 อีกครั้ง INC HL

40 60005 DJNZ อีกครั้ง

3.2.

250 260 270

60110 60111 60113

LD A,(HL) CP 80H JR NZ,เริ่มต้น

อย่างที่คุณเห็นมันสะดวกมาก คุณจะเห็นได้ทันทีว่าจากบรรทัดที่ 40 การส่งคืนจะอยู่ที่ป้ายกำกับ AGAIN หากรีจิสเตอร์ B ไม่ถึงศูนย์ บรรทัด 270 กลับสู่ป้ายกำกับ BEGIN

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

ในระหว่างการคอมไพล์โปรแกรมแอสเซมบลีจะคำนวณค่าออฟเซ็ตที่ต้องการในคำสั่งของโปรเซสเซอร์และแทนที่ค่าเหล่านั้นแทนป้ายกำกับ ตัวอย่างเช่น ในบรรทัดที่ 40 แทนที่จะเป็น DJNZ AGAIN ออบเจ็กต์โค้ดจะมี DJNZ FCH ซึ่งเป็นสิ่งเดียวกัน

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

ตัวอย่างเช่น ในโปรแกรมของคุณ คุณต้องเรียกโพรซีเดอร์ ROM ซ้ำๆ เช่น CLEAR (1EACH=7 8 52) และ OUT-LINE (1856H=6230) จากนั้นเมื่อเริ่มต้นโปรแกรมคุณระบุ

เช่นเรียกพวกเขาว่า CLEAR

คำสั่ง

ค่าของป้ายกำกับ n

และ OUT L.

ชัดเจน

อีคิว 7 8 52

ออก แอล

อีคิว 62 3 0

ฉลาก

อีคิว 60016

เรียก

คุณรู้สิ่งเหล่านี้

ขั้นตอนหรือ

โดยมาร์ก

60001

แอลดี เอชแอล, (ฉลาก)

60004

แอลดี ก่อนคริสต์ศักราช, 0008

60007

แอลดี ดีอี, (04 52)

60010

โทรเคลียร์

60013

โทรหาแอล

60016

ตรงไปตรงมา

เป็นหนี้คุณ

เตือน,

ตัวอย่าง

จากมุมมอง

ซอฟต์แวร์

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

ลองมาดูตัวอย่างก่อนหน้านี้อีกครั้ง ในบรรทัดที่ 30 เราส่งสิ่งที่มีอยู่ในที่อยู่ซึ่งชี้ไปที่ฉลาก LABEL ไปยังคู่รีจิสเตอร์ HL ซึ่งตามคำสั่ง EQU ชี้ไปยังที่อยู่ 60016

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

DEFB - กำหนดไบต์ - ตั้งค่าไบต์

DEFW - DEFINE WORD - ตั้งค่า "word" ("word" คือไบต์สองไบต์ติดต่อกัน โดยปกติจะเป็นที่อยู่) DEFM - DEFINE MESSAGE - ตั้งค่าข้อความ (ซึ่งเป็นไบต์หลายไบต์ติดต่อกัน) โดยทั่วไป โปรแกรมแอสเซมบลีกำหนดขีดจำกัดจำนวนไบต์ที่สามารถระบุได้โดยคำสั่ง DEFM หนึ่งคำสั่ง กล่าวคือไม่เกินห้าไบต์ แต่สิ่งนี้ไม่ควรกังวลคุณ หากคุณต้องการระบุข้อความที่ยาว คุณสามารถใส่บรรทัด DEFM ในแถวได้มากเท่าที่คุณต้องการ

ดังนั้น DEFB ระบุหนึ่งไบต์เดียว (0...255) DEFW ระบุสองไบต์ติดต่อกัน (0...65535) และ DEFM ระบุกลุ่มของไบต์ต่อเนื่องกัน - ข้อความ, ตารางหมายเลขฯลฯ

ในตัวอย่างก่อนหน้านี้ หากเราต้องการเก็บตัวเลขสองไบต์ไว้ที่ที่อยู่ 60016 และ 60017 บรรทัด 80 จะต้องเขียนดังนี้:

80 60016 DEFW 5C92H

90 60018

สมมติว่าคุณต้องการเก็บคำว่า "Spectrum" โดยเริ่มต้นที่ที่อยู่ 60135

รหัสตัวอักษร "S" รหัสตัวอักษร "p" "e" "c" "t" "r"

"คุณ" "ม"

60135

60136

60137

60138

60139

60140

60141

60142

53H 7 0H 65H 63H 7 4H 72H 75H 6DH

DEFB DEFB DEFB DEFB DEFB DEFB DEFB DEFB

คุณสามารถระบุเป็นคู่ไบต์:

แต่จะง่ายกว่าและถูกต้องมากกว่าหากตั้งเป็นข้อความ:

60135 เดฟเอ็ม 5370656374 ; "สเปค"

60140 DEFM 72756D ; "เหล้ารัม"

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

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

ในส่วนแรกของหนังสือ เราใช้สัญลักษณ์ช่วยจำสำหรับคำสั่งเครื่องคิดเลข เช่น add, stk_data s_lt ฯลฯ และเขียนด้วยตัวอักษรตัวเล็ก ตรงกันข้ามกับคำสั่งตัวประมวลผล แต่เราเคยทำเช่นนี้มาก่อนและจะทำต่อไปเพียงเพื่อความเข้าใจและความง่ายในการบันทึกเท่านั้น โปรแกรม ASSEMBLY ไม่รู้จักตัวช่วยจำดังกล่าว ไม่มีอยู่ในพจนานุกรม

ดังนั้นด้วยความช่วยเหลือของ DEFB, DEFW และ DEFM พวกเขาตั้งค่าเริ่มต้นของตัวแปรโปรแกรมป้อนตารางข้อความและลำดับข้อมูลอื่น ๆ ลงในโปรแกรมแม้กระทั่ง

กราฟิกตลอดจนลำดับโค้ดที่โปรแกรมแอสเซมบลีไม่เข้าใจเป็นคำสั่ง ASSEMBLY

3.5. คำสั่ง ORG, END

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

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

10 องค์กร 63000

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

คำสั่ง END เป็นจุดสิ้นสุดของโปรแกรม หากมีอย่างอื่นหลังจากนั้น ASSEMBLY จะเพิกเฉยต่อในระหว่างการคอมไพล์

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

เมื่อเขียนโปรแกรมในภาษาแอสเซมบลีจะใช้คำสั่งที่ระบุตำแหน่งของโปรแกรมในหน่วยความจำให้คอมไพเลอร์กำหนดมาโครเริ่มต้นหน่วยความจำ ฯลฯ รายการคำสั่งและคำอธิบายมีอยู่ในตาราง 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 ใช้เพื่อควบคุมเอาต์พุตของรายการ

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 (ชื่อเชิงสัญลักษณ์)

คำสั่ง .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 เริ่มต้น

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

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

Macro set_bit ; ประกาศแมโครสำหรับการตั้งค่าบิตพอร์ต sbi @0,@1 ; set bit @1 ของพอร์ต register @0 sbi @0-1,@1 ; set line @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 "อาร์กิวเมนต์แมโครผิด!" กลุ่มของ directives การคอมไพล์แบบมีเงื่อนไข.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 (เงื่อนไข))
ตัวอย่างการใช้งาน:

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

ตัวประกอบ 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 (เลขทศนิยม

เริ่มต้น: 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 สิ้นสุดโปรแกรมโดยระบุว่าควรเริ่มต้นการดำเนินการที่จุดใด