มันไม่ย่อท้อ
+=
สัญลักษณ์ที่ปรากฏในภาษา C ในปี 1970 และ - มีความคิดที่ C ของ "แอสเซมสมาร์ท" สอดคล้องกับการเรียนการสอนและเครื่อง adressing โหมดที่แตกต่างกันอย่างชัดเจน
สิ่งต่าง ๆ เช่น " i=i+1
", "i+=1
"และ" ++i
", ถึงแม้ว่าในระดับนามธรรมจะให้เอฟเฟกต์แบบเดียวกัน แต่ก็จะทำงานในระดับต่ำกับวิธีการทำงานของโปรเซสเซอร์ที่แตกต่างกัน
โดยเฉพาะนิพจน์ทั้งสามนั้นสมมติว่าi
ตัวแปรอยู่ในหน่วยความจำที่เก็บไว้ใน CPU register (ลองตั้งชื่อD
- คิดว่ามันเป็น "ตัวชี้ไปยัง int") และALUของโปรเซสเซอร์ใช้พารามิเตอร์และส่งกลับผลลัพธ์ใน "แอคคูมูเลเตอร์" (เรียกมันว่าเอ - คิดว่ามันเป็น int)
ด้วยข้อ จำกัด เหล่านี้ (พบได้บ่อยมากในไมโครโปรเซสเซอร์ทั้งหมดจากช่วงเวลานั้น) การแปลน่าจะเป็นไปได้มากที่สุด
;i = i+1;
MOV A,(D); //Move in A the content of the memory whose address is in D
ADD A, 1; //The addition of an inlined constant
MOV (D) A; //Move the result back to i (this is the '=' of the expression)
;i+=1;
ADD (D),1; //Add an inlined constant to a memory address stored value
;++i;
INC (D); //Just "tick" a memory located counter
วิธีแรกของการทำเช่นนี้เป็นสิ่งที่ไม่น่าพอใจ แต่มันก็เป็นเรื่องทั่วไปมากขึ้นเมื่อใช้งานกับตัวแปรแทนที่จะเป็นค่าคงที่ ( ADD A, B
หรือADD A, (D+x)
) หรือเมื่อแปลนิพจน์ที่ซับซ้อนมากขึ้น (พวกมันทั้งหมดต้มลงในการดำเนินการ และทำซ้ำจนกว่าข้อโต้แย้งทั้งหมดจะหมดไป)
ข้อที่สองเป็นเรื่องปกติมากขึ้นของ "state machine": เราไม่ได้ "ประเมินนิพจน์" อีกต่อไป แต่ "ปฏิบัติการค่า": เรายังคงใช้ ALU แต่หลีกเลี่ยงการเคลื่อนย้ายค่าโดยรอบเป็นผลลัพธ์ที่ได้รับอนุญาตให้แทนที่พารามิเตอร์ การเรียนการสอนประเภทนี้ไม่สามารถใช้ในกรณีที่จำเป็นต้องใช้การแสดงออกที่ซับซ้อนมากขึ้น: i = 3*i + i-2
ไม่สามารถดำเนินการในสถานที่เนื่องจากi
ต้องใช้เวลามากขึ้น
สิบเอ็ดง่ายกว่า - ไม่ได้พิจารณาแนวคิดของ "การเพิ่ม" แต่ใช้วงจร "ดั้งเดิม" (ในแง่การคำนวณ) มากกว่าสำหรับตัวนับ คำแนะนำสั้นโหลดเร็วขึ้นและดำเนินการทันทีเนื่องจากเครือข่าย combinatorial จำเป็นต้องทำการติดตั้งเพิ่มใหม่เพื่อให้ตัวนับมีขนาดเล็กลงและเร็วกว่าแอดเดอร์ตัวเต็ม
ด้วยคอมไพเลอร์ร่วมสมัย (อ้างถึง C, โดยตอนนี้), การเปิดใช้งานการเพิ่มประสิทธิภาพคอมไพเลอร์, การโต้ตอบสามารถสลับตามความสะดวกสบาย, แต่ยังคงมีความแตกต่างทางแนวคิดในความหมาย
x += 5
วิธี
- ค้นหาสถานที่ที่ระบุโดย x
- เพิ่ม 5 เข้าไป
แต่x = x + 5
หมายถึง:
- ประเมิน x + 5
- ค้นหาสถานที่ที่ระบุโดย x
- คัดลอก x ไปยังแอคคูมูเลเตอร์
- เพิ่ม 5 ไปยังตัวสะสม
- เก็บผลลัพธ์ใน x
- ค้นหาสถานที่ที่ระบุโดย x
- คัดลอกสะสมไป
แน่นอนการเพิ่มประสิทธิภาพสามารถ
- หาก "การค้นหา x" ไม่มีผลข้างเคียงทั้งสอง "การค้นหา" สามารถทำได้หนึ่งครั้ง (และ x กลายเป็นที่อยู่ที่เก็บไว้ในการลงทะเบียนตัวชี้)
- สามารถคัดลอกทั้งสองชุดได้หากมีการใช้ ADD
&x
แทนการสะสม
จึงทำให้รหัสที่ดีที่สุดให้ตรงx += 5
หนึ่ง
แต่สิ่งนี้สามารถทำได้ก็ต่อเมื่อ "การค้นหา x" ไม่มีผลข้างเคียง
*(x()) = *(x()) + 5;
และ
*(x()) += 5;
มีความแตกต่างทางความหมายเนื่องจากx()
ผลข้างเคียง (การยอมรับว่าx()
เป็นฟังก์ชั่นที่ทำสิ่งแปลก ๆ และส่งคืนint*
) จะถูกสร้างขึ้นสองครั้งหรือครั้งเดียว
ความเท่าเทียมกันระหว่างx = x + y
และx += y
เป็นเพราะกรณีเฉพาะที่+=
และ=
นำไปใช้กับค่า l โดยตรง
ในการย้ายไปยัง Python มันจะสืบทอดไวยากรณ์จาก C แต่เนื่องจากไม่มีการแปล / การปรับให้เหมาะสมก่อนการดำเนินการในภาษาที่แปลสิ่งต่าง ๆ ไม่จำเป็นต้องเกี่ยวข้องกันอย่างใกล้ชิด (เนื่องจากมีขั้นตอนการแยกวิเคราะห์น้อยกว่า) อย่างไรก็ตามล่ามสามารถอ้างถึงรูทีนการประมวลผลที่แตกต่างกันสำหรับนิพจน์ทั้งสามประเภทโดยใช้ประโยชน์จากรหัสเครื่องที่แตกต่างกันขึ้นอยู่กับว่านิพจน์เกิดขึ้นและบริบทการประเมินผลอย่างไร
สำหรับผู้ที่ชื่นชอบรายละเอียดเพิ่มเติม ...
CPU ทุกตัวมี ALU (หน่วยคำนวณเชิงตรรกะ) ซึ่งก็คือเครือข่าย combinatorial ซึ่งอินพุตและเอาต์พุตนั้น "เสียบ" กับรีจิสเตอร์และ / หรือหน่วยความจำขึ้นอยู่กับ opcode ของคำสั่ง
โดยทั่วไปแล้วการดำเนินการแบบไบนารีจะดำเนินการในฐานะ "ตัวดัดแปลงของการลงทะเบียนแบบสะสมพร้อมอินพุตที่นำมา" ที่ไหนสักแห่ง "ซึ่งบางที่สามารถ - ภายในขั้นตอนการสอนเอง ขมับ: เช่น ADD AB) - ภายในหน่วยความจำตามที่อยู่ที่กำหนดโดยการลงทะเบียน (ปกติของการดึงข้อมูลเช่น: ADD A (H)) - H ในกรณีนี้ทำงานเหมือนตัวชี้การประชุม
ด้วยรหัสเทียมนี้x += 5
คือ
ADD (X) 5
ในขณะที่x = x+5
เป็น
MOVE A (X)
ADD A 5
MOVE (X) A
นั่นคือ x + 5 ให้ชั่วคราวที่ได้รับมอบหมายในภายหลัง x += 5
ทำงานโดยตรงกับ x
การใช้งานจริงขึ้นอยู่กับชุดคำสั่งจริงของโปรเซสเซอร์: หากไม่มีADD (.) c
opcode รหัสแรกจะกลายเป็นครั้งที่สอง: ไม่มีทาง
หากมีรหัสดังกล่าวและมีการเปิดใช้งานการเพิ่มประสิทธิภาพการแสดงออกที่สองหลังจากที่กำจัดการย้ายย้อนกลับและปรับการลงทะเบียน opcode กลายเป็นครั้งแรก
x += 5
กว่าx = x + 5
? หรือมันเป็นเพียงแค่น้ำตาลทรายตามที่คุณแนะนำ?