ภาษาแอสsemblีและโหมดการเข้าถึงหน่วยความจำ
แนะนำใหม่| English | ความหมาย |
|---|---|
| assembler/əˈsemblə/ | อสมบิลเลอร์ |
| mnemonic/nɪˈmɒnɪk/ | มเนโมนิค |
| instruction set/ɪnˈstrʌkʃn set/ | ชุดคำสั่ง |
| machine code/məˈʃiːn kəʊd/ | โค้ดเครื่อง |
| assembly language/əˈsemblɪ ˈlæŋɡwɪdʒ/ | ภาษาอสมบิล |
| operand/ˈɒpərænd/ | ออปperaנד |
| opcode/ˈɒpkəʊd/ | โอเปค |
| symbol table/ˈsɪmbl ˈteɪbl/ | ตารางสัญลักษณ์ |
| label/ˈleɪbl/ | ฉลาก |
| forward references/ˈfɔːwəd ˈrefrənsɪz/ | การอ้างอิงไปข้างหน้า |
| addressing mode/əˈdresɪŋ məʊd/ | โหมดการเข้าถึง |
| immediate addressing/ɪˈmiːdɪət əˈdresɪŋ/ | การเข้าถึงแบบทันที |
| direct addressing/daɪˈrekt əˈdresɪŋ/ | การเข้าถึงโดยตรง |
| indirect addressing/ɪndaɪˈrekt əˈdresɪŋ/ | การเข้าถึงแบบอ้อม |
| indexed addressing/ˈɪndekst əˈdresɪŋ/ | การเข้าถึงแบบดรรชนี |
| relative addressing/ˈrelətɪv əˈdresɪŋ/ | การเข้าถึงแบบสัมพัทธ์ |
คำสั่งสามสิบหนึ่งบรรทัดเรียงกันบนสวิตช์
- ในปี ค.ศ. 1949 คอมพิวเตอร์ EDSAC ในเคมบริดจ์เริ่มทำงานจากคำสั่ง 31 บรรทัดที่ตั้งอยู่บนสวิตช์ ซึ่งเขียนโดย David Wheeler และเรียกว่า "initial orders"
- งานทั้งหมดของพวกเขาคือการอ่านตัวอักษรเช่น A และ S จากเทปกระดาษและแปลงให้เป็นตัวเลขที่เครื่องเข้าใจได้จริง: นี่คือ assembler ตัวแรก
- ตั้งแต่นั้นมา โปรแกรมเมอร์ก็เขียน mnemonics แทนรูปแบบบิต และชุดคำสั่งของข้อสอบก็เป็นลูกหลานโดยตรงของสิ่งนี้
- บทเรียนนี้เกี่ยวกับการแปลนั้น การติดตามโปรแกรมด้วยมือ และห้าวิธีที่คำสั่งสามารถระบุตำแหน่งของข้อมูลได้
รหัสเครื่องและภาษาแอสsemblี
- โปรเซสเซอร์รัน machine code: รูปแบบบิตเฉพาะสำหรับสถาปัตยกรรมหนึ่งๆ แต่ละอันคือ operation code และ operand
- Assembly language คือรูปแบบที่อ่านง่าย Each instruction เขียนด้วย mnemonic เช่น
LDD,ADDหรือJMPและแต่ละ assembly instruction จะกลายเป็น machine-code instruction ที่แน่นอนหนึ่งinstruction - Assembler แปลมัน ความสัมพันธ์คือหนึ่งต่อหนึ่ง ซึ่งเป็นสิ่งที่ทำให้แอสsemblีแตกต่างจาก high-level language ที่ statement หนึ่งกลายเป็นหลายคำสั่ง

Mnemonic แต่ละอันกลายเป็น opcode หนึ่ง; symbolic address แต่ละอันกลายเป็นตัวเลข
ภาษาแอสsembly คือ:
Difficulty 1/5 · 100 coins + a small bonus on first completion today
แอสsembly ใช้ mnemonics และจับคู่กับ machine code แบบหนึ่งต่อหนึ่ง; assembler จะทำการแปลมัน
Assembler แบบสองรอบ
- Pass 1 อ่าน source และสร้าง symbol table: ทุกครั้งที่ label เช่น
LOOP:ปรากฏขึ้น ADDRESS จะถูกบันทึก ไม่มีโค้ดที่ถูกผลิตออกมา - Pass 2 อ่าน source อีกครั้งและสร้างโค้ด โดยแทนที่ mnemonics ด้วย opcode และแทนที่ symbolic addresses ด้วยตัวเลขจาก symbol table
- ต้องใช้สองรอบเนื่องจาก forward references:
JMP LOOPอาจปรากฏก่อนบรรทัดLOOP:ถูกมองเห็น ดังนั้น ADDRESS ของมันจึงไม่ทราบในรอบแรก
การผ่าน 1 ของ two-pass assembler ทำอะไร?
Difficulty 1/5 · 100 coins + a small bonus on first completion today
Pass 1 บันทึกตำแหน่งของแต่ละ label (symbol table); จากนั้น pass 2 จะสร้างโค้ด โดยใช้ตารางเพื่อแก้การอ้างอิง label
เรียงลำดับการทำงานของ two-pass assembler ให้ถูกต้อง
Difficulty 3/5 · 200 coins + a small bonus on first completion today
Pass 1 ค้นหา labels ทั้งหมดก่อน เพื่อให้ pass 2 สามารถแก้ even jump ไปยัง label ที่นิยามไว้ทีหลังได้
ทำไม assembler จึงต้องใช้สอง passes?
Difficulty 1/5 · 100 coins + a small bonus on first completion today
คำสั่งกระโดดอาจชี้ไปยังฉลากที่ปรากฏในซอร์สโค้ดทีหลัง; การผ่าน 1 จะค้นหาฉลากทั้งหมดก่อน เพื่อให้การผ่าน 2 สามารถแก้ความไม่แน่นอนของฉลากเหล่านั้นได้
ตัวอย่างการคำนวณ: การประยุกต์ใช้สองรอบ
- โปรแกรมเริ่มต้นที่ ADDRESS 100
100 LDD COUNT
101 LOOP: DEC ACC
102 CMP #0
103 JPN LOOP
104 END
105 COUNT: 5
- Pass 1 นับ ADDRESS ของแต่ละบรรทัดและบันทึก labels:
LOOP= 101,COUNT= 105 ไม่มีการเขียนอะไรอื่น - Pass 2 แปลบรรทัดต่อบรรทัด
LDD COUNTกลายเป็น opcode สำหรับLDDพร้อม operand 105;JPN LOOPกลายเป็น opcode สำหรับJPNพร้อม operand 101 หากไม่มี pass 1 บรรทัดแรกจะไม่สามารถแปลได้
วิธีการทำงานของแอสsembl์แบบสองรอบ
ลองเดินตามกระบวนการดู แอสsembl์จะอ่านโค้ดของคุณสองครั้ง: รอบ 1 จะหาตำแหน่งของแต่ละฉลาก (label) เพื่อให้อรอบ 2 สามารถกรอกที่อยู่ได้ — นั่นคือเหตุผลว่าทำไมการกระโดดไปยังฉลากที่นิยาม ภายหลัง จึงยังทำงานได้
ในตัวอย่างวิธีทำ, การผ่าน 1 จะบันทึกฉลาก LOOP พร้อมที่อยู่ ____ ในตารางสัญลักษณ์
Difficulty 1/5 · 100 coins + a small bonus on first completion today
โปรแกรมเริ่มต้นที่ 100, ดังนั้นบรรทัดที่สอง, LOOP: DEC ACC, จึงอยู่ที่ 101. COUNT, บนบรรทัดที่หก, มีค่าที่ 105
ชุดคำสั่ง
- ชุดคำสั่งของเคมบริดจ์มี general-purpose register หนึ่งตัวคือ accumulator ACC และ index register IX Operand
#nเป็นฐานสิบ,Bnเป็นฐานสอง,&nเป็นฐานหกteen, และ<address>เป็นหมายเลขสถานที่หรือ label - การเคลื่อนย้ายข้อมูล:
LDM #n,LDD <address>,LDI <address>,LDX <address>,LDR #n,MOV IX,STO <address>อินพุตและเอาต์พุต:IN,OUT - การคำนวณทางคณิตศาสตร์:
ADD,SUB,INC,DECเปรียบเทียบ:CMP,CMIการกระโดด:JMPแบบไม่เงื่อนไข,JPEและJPNแบบเงื่อนไข การจัดการบิต:AND,OR,XOR,LSL,LSRจากนั้นEND - "คำสั่งถูกจัดกลุ่ม": ชื่อกลุ่มและยกตัวอย่างคำสั่งหนึ่งจากแต่ละกลุ่ม
ข้อใดต่อไปนี้屬於กลุ่มคำสั่งในชุดคำสั่ง? เลือก ทุก ข้อที่ถูกต้อง
Difficulty 2/5 · 140 coins + a small bonus on first completion today
การเคลื่อนย้ายข้อมูล, อินพุต/เอาต์พุต, คณิตศาสตร์, เปรียบเทียบ, การกระโดดแบบมีเงื่อนไขและไม่有条件的, และการจัดการบิต สเปรดชีตเป็นซอฟต์แวร์ประยุกต์ ซึ่งสูงกว่าระดับนี้มาก
ตัวอย่างการคำนวณ: การติดตามโปรแกรม
- วาดตารางที่มีคอลัมน์สำหรับ ACC และสำหรับทุก memory location ที่โปรแกรมใช้ แล้วอัปเดตทีละบรรทัดจนกว่าจะถึง
END
100 LDM #0
101 STO TOTAL
102 LDD TOTAL
103 ADD #5
104 STO TOTAL
105 LDD COUNT
106 DEC ACC
107 STO COUNT
108 CMP #0
109 JPN 102
110 END
111 TOTAL: 0
112 COUNT: 3
- Pass 1 ของลูป: ACC 0 → 5 (TOTAL = 5), COUNT 3 → 2, เปรียบเทียบไม่เท่ากัน, กระโดด Pass 2: TOTAL = 10, COUNT = 1, กระโดด Pass 3: TOTAL = 15, COUNT = 0, เปรียบเทียบเท่ากัน, ไม่กระโดด,
END - ค่าสุดท้าย: TOTAL = 15, COUNT = 0, ACC = 0 เขียนแถวใหม่ก็ต่อเมื่อค่าเปลี่ยนไปและไม่ควรข้ามขั้นตอนการเปรียบเทียบเด็ดขาด
ในโปรแกรมที่ติดตาม, ค่าของ TOTAL คืออะไรเมื่อถึง END?
Difficulty 2/5 · 140 coins + a small bonus on first completion today
ลูปจะเพิ่ม 5 เข้ากับ TOTAL ครั้งละหนึ่งครั้งสำหรับแต่ละรอบของสามรอบ: 5, 10, 15
โหมดการอ้างอิงที่อยู่ (Addressing modes)
- Addressing mode บอกว่าโปรเซสเซอร์หา operand ได้อย่างไร
| Mode | ตำแหน่งของ operand | ตัวอย่าง |
|---|---|---|
| immediate addressing | ค่าอยู่ในตัวคำสั่งเอง | LDM #10 โหลด 10 |
| direct addressing | คำสั่งมี ADDRESS; ใช้ค่าที่เก็บไว้นั้น | LDD 200 โหลดเนื้อหาของ 200 |
| indirect addressing | Address มีอีก address หนึ่งซึ่งมีข้อมูลอยู่ | LDI 200 |
| indexed addressing | effective address = address ที่ให้มา + index register | LDX 200 กับ IX |
| relative addressing | Address เป็น offset จากคำสั่งปัจจุบัน | การกระโดด |

*ฟิลด์ operand เดียวกัน ความหมายสี่แบบต่างกัน
ในการจัดตำแหน่งแบบทันที (เช่น LDM #10), оперant คือ:
Difficulty 1/5 · 100 coins + a small bonus on first completion today
การอ้างอิงแบบทันที (Immediate addressing) ใช้ค่าตัวอักษรในคำสั่ง (ในที่นี้คือ 10)
จับคู่โหมดการอ้างอิงแต่ละประเภทกับความหมายของมัน
Difficulty 2/5 · 140 coins + a small bonus on first completion today
ทันที = ค่า; โดยตรง = ที่อยู่ของค่า; ทางอ้อม = ที่อยู่ของที่อยู่; แบบมีดัชนี = ที่อยู่ฐาน + ดัชนี
ตัวอย่างการคำนวณ: หนึ่ง operand สี่คำตอบ
- Memory: Location 200 เก็บ 300, Location 300 เก็บ 7, Location 202 เก็บ 9 Index register IX เก็บ 2
LDM #200ใส่ 200 ลงใน ACC: Immediate, ตัวเลข itselfLDD 200ใส่ 300 ลงใน ACC: Direct, เนื้อหาของ 200LDI 200ใส่ 7 ลงใน ACC: Indirect, เนื้อหาของ address ที่พบที่ 200LDX 200บวก IX เข้ากับ 200 และโหลดเนื้อหาของ 202: 9 Operand เดียวกันเขียนสี่แบบ สี่ค่าต่างกัน
เหตุผลที่มี indexed addressing
- Array คือ سلسلةของ locations ที่ต่อเนื่องกัน
LDX 200กับ IX = 0, 1, 2, … อ่าน element 0, 1, 2, … โดยไม่ต้องเปลี่ยนคำสั่ง - รูปแบบลูป:
LDR #0ตั้งค่าดัชนีเป็นศูนย์,LDX ARRAYดึงข้อมูลมา, ทำการใด某อย่าง,INC IXเปรียบเทียบกับความยาว,JPNกลับไป. - การเข้าถึงโดยตรงจำเป็นต้องใช้คำสั่งแยกสำหรับแต่ละข้อมูล; การเข้าถึงแบบดรรชนีใช้เพียงหนึ่งเดียว.
การหาที่อยู่แบบมีดัชนีจะมีประโยชน์มากที่สุดสำหรับ:
Difficulty 1/5 · 100 coins + a small bonus on first completion today
ที่อยู่ที่มีผลคือ ที่อยู่ฐาน + รีจิสเตอร์ดัชนี ดังนั้นการเพิ่มค่าดัชนีจึงทำให้วนลูปผ่านอาร์เรย์ได้
เปรียบเทียบและกระโดด
CMP #nหรือCMP <address>เปรียบเทียบ ACC กับค่าหนึ่งและตั้งค่าบิตสถานะ (flag) มัน ไม่ เปลี่ยนแปลงค่าของ ACC.JPE <address>จะกระโดดหากผลการเปรียบเทียบล่าสุดพบว่าค่าเท่ากัน;JPN <address>จะกระโดดหากค่าไม่เท่ากัน;JMP <address>กระโดดเสมอ.- คำสั่งในภาษาระดับสูง
IFจะกลายเป็นCMPตามด้วยการกระโดดตามเงื่อนไข; ลูปจะประกอบด้วยขั้นตอนเปรียบเทียบและการกระโดดกลับไปยังฉลาก.
CMP #0 เปลี่ยนค่าที่เก็บอยู่ในแอคคูมิูลเตอร์
Difficulty 1/5 · 100 coins + a small bonus on first completion today
คำสั่งเปรียบเทียบจะกำหนดค่าเฟล็กเท่านั้นที่คำสั่งกระโดดตามเงื่อนไขถัดไปจะอ่านใช้ แอคคูมิูลเตอร์ไม่ถูกเปลี่ยนไป นี่คือเหตุผลว่าทำไมในเทรซจึงไม่แสดงค่า ACC ใหม่บนบรรทัด CMP
คะแนนที่หลุดหายไป
LDM #10โหลดตัวเลข 10;LDD 10โหลดเนื้อหาจากตำแหน่งที่ 10. ส่วน#คือความแตกต่างทั้งหมด.#เป็นฐานสิบ,Bเป็นฐานสอง,&เป็นฐานหก عشر.AND &0FและAND B00001111เป็นมาสก์เดียวกัน;AND #15ก็เช่นกัน.CMPไม่ touched ค่า ACC; มันตั้งค่าบิตสถานะเท่านั้น.JPNจะกระโดดเมื่อค่า ไม่ เท่ากัน.- การผ่านครั้งที่ 1 ของโปรแกรมแปลภาษาแอสเซมบลี ไม่ได้ สร้างโค้ด. ผลลัพธ์คือตารางสัญลักษณ์ และการอ้างอิงถึงอนาคตคือเหตุผลในการมีอยู่ของมัน.
คุณเข้าใจแล้ว
- โค้ดเครื่อง คือรูปแบบบิต; แอสเซมบลี คือคำนำหน้า (mnemonics), แบบหนึ่งต่อหนึ่ง, ถูกแปลโดย โปรแกรมนำเข้า
- สองรอบ: รอบที่ 1 สร้าง ตารางสัญลักษณ์ ของที่อยู่ฉลาก, รอบที่ 2 สร้างโค้ด; จำเป็นสำหรับการ อ้างอิงถึงอนาคต
- เทรส ด้วยตารางของ ACC และทุกตำแหน่ง,หนึ่งแถวต่อการเปลี่ยนแปลง; CMP ตั้งค่าบิตสถานะ, JPE/JPN อ่านค่ามัน
- การเข้าถึง: ทันที
#nค่า · โดยตรง เนื้อหาของที่อยู่ · อ้อม ที่อยู่ของที่อยู่ · ดรรชนี ที่อยู่ + IX (อาเรย์) · สัมพัทธ์ การเบี่ยงเบน