อะไรคือความแตกต่างระหว่าง MOV และ LEA?


144

ฉันต้องการทราบความแตกต่างระหว่างคำแนะนำเหล่านี้:

MOV AX, [TABLE-ADDR]

และ

LEA AX, [TABLE-ADDR]


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

3
ฉันโหวต dup ของ @ Nick เมื่อหลายปีก่อน แต่ vtc เพิ่งจะตอนนี้ ในการไตร่ตรองฉันรีบเกินไปและตอนนี้กับ naveen ว่า a) คำถามอื่นไม่ได้คำตอบว่า "อะไรคือความแตกต่าง" และ b) นี่เป็นคำถามที่มีประโยชน์ ขออภัยในความผิดพลาดของฉัน - ถ้าเพียงฉันสามารถยกเลิก vtc ...
Ruben Bartelink


ที่เกี่ยวข้อง: การใช้ LEA กับค่าที่ไม่ใช่ที่อยู่ / ตัวชี้? พูดถึงการใช้งานอื่น ๆ ของ LEA สำหรับคณิตศาสตร์ตามอำเภอใจ
Peter Cordes

คำตอบ:


176
  • LEA หมายถึงโหลดที่อยู่ที่มีประสิทธิภาพ
  • MOV หมายถึง Load Value

ในระยะสั้นLEAโหลดตัวชี้ไปยังรายการที่คุณกำลังกล่าวถึงในขณะที่ MOV โหลดค่าจริงตามที่อยู่นั้น

จุดประสงค์LEAคือเพื่อให้หนึ่งทำการคำนวณที่อยู่ที่ไม่สำคัญและเก็บผลลัพธ์ไว้ [สำหรับการใช้งานในภายหลัง]

LEA ax, [BP+SI+5] ; Compute address of value

MOV ax, [BP+SI+5] ; Load value at that address

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


6
+1 ขอบคุณสำหรับคำอธิบายที่ชัดเจนช่วยฉันตอบคำถามอื่น
legends2k

ทำให้ฉันสับสนว่า lea มี "load" ในชื่อและมีคนบอกว่า "โหลด" ที่อยู่ที่คำนวณลงในรีจิสเตอร์เนื่องจากอินพุตทั้งหมดในการคำนวณตำแหน่งหน่วยความจำนั้นเป็นค่าทันทีหรือรีจิสเตอร์ AFAICT lea ทำการคำนวณเท่านั้นไม่โหลดอะไรเลยการโหลดหมายถึงการสัมผัสหน่วยความจำ?
Joseph Garvin

2
@josephGarvin IIRC คำว่าดึงข้อมูลจะถูกนำไปใช้กับด้านนั้น โหลดเป็นเพียงวิธีที่คุณแทนที่ค่าในรีจิสเตอร์ด้วยบางสิ่งตั้งแต่เริ่มต้น เช่นLAHFเป็น: ธงโหลดลงใน AH ลงทะเบียน ใน CIL ของ CLR (ซึ่งเป็นเครื่องนามธรรมที่ใช้สแต็กในระดับที่สูงขึ้นคำว่าloadหมายถึงการใส่ค่าลงในสแต็กเชิงสัญกรณ์และโดยปกติl... และs... เทียบเท่าจะผกผัน) หมายเหตุเหล่านี้: cs.umd.edu/class/sum2003/cmsc311/Notes/Mips/load.html ) แนะนำว่ามีสถาปัตยกรรมที่ใช้ความแตกต่างของคุณ
Ruben Bartelink

1
ทุกอย่างทำให้ฉันนึกถึงslideshare.net/pirhilton/… ;)
Ruben Bartelink

47

ในไวยากรณ์ NASM:

mov eax, var       == lea eax, [var]   ; i.e. mov r32, imm32
lea eax, [var+16]  == mov eax, var+16
lea eax, [eax*4]   == shl eax, 2        ; but without setting flags

ในไวยากรณ์ MASM ใช้OFFSET varเพื่อรับ mov ทันทีแทนการโหลด


4
ในไวยากรณ์ NASM เท่านั้น ในไวยากรณ์ MASM mov eax, varคือการโหลดเช่นเดียวกับmov eax, [var]และคุณต้องใช้mov eax, OFFSET varเพื่อใช้ป้ายกำกับเป็นค่าคงที่ทันที
Peter Cordes

1
ชัดเจนเรียบง่ายและแสดงให้เห็นถึงสิ่งที่ฉันพยายามยืนยัน ขอบคุณ.
JayArby

1
โปรดทราบว่าในตัวอย่างทั้งหมดนี้leaเป็นตัวเลือกที่แย่กว่ายกเว้นในโหมด 64 บิตสำหรับการกำหนดแอดเดรสแบบสัมพันธ์ RIP mov r32, imm32ทำงานบนพอร์ตเพิ่มเติม lea eax, [edx*4]เป็นสำเนาและกะซึ่งไม่สามารถทำได้ในคำสั่งเดียวเป็นอย่างอื่น แต่ในการลงทะเบียนเดียวกัน LEA ใช้เวลาในการเข้ารหัสมากกว่าไบต์เนื่องจาก[eax*4]ต้องใช้ไฟล์disp32=0. (มันทำงานบนพอร์ตที่แตกต่างกว่ากะแม้ว่า.) ดูagner.org/optimizeและstackoverflow.com/tags/x86/info
Peter Cordes

31

คำสั่ง MOV reg, addr หมายถึงอ่านตัวแปรที่เก็บไว้ที่แอดเดรส addr ลงใน register reg คำสั่ง LEA reg, addr หมายถึงอ่านที่อยู่ (ไม่ใช่ตัวแปรที่เก็บไว้ที่ที่อยู่) ลงใน register reg

อีกรูปแบบหนึ่งของคำสั่ง MOV คือ MOV reg, immdata ซึ่งหมายถึงอ่านข้อมูลทันที (เช่นค่าคงที่) immdata ลงใน register reg โปรดทราบว่าถ้า addr ใน LEA reg, addr เป็นเพียงค่าคงที่ (เช่นออฟเซ็ตคงที่) ดังนั้นคำสั่ง LEA นั้นจะเหมือนกับ MOV reg ที่เท่ากันทุกประการคำสั่ง immdata ที่โหลดค่าคงที่เดียวกันกับข้อมูลทันที


11

หากคุณระบุเพียงตัวอักษรไม่มีความแตกต่าง อย่างไรก็ตาม LEA มีความสามารถมากกว่านี้และคุณสามารถอ่านเกี่ยวกับพวกเขาได้ที่นี่:

http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_6/CH06-1.html#HEADING1-136


ฉันเดาว่ามีข้อยกเว้นว่าในแอสเซมเบลอร์ GNU ไม่เป็นความจริงเมื่อพูดถึงป้ายกำกับในเซ็กเมนต์. bss? AFAIR คุณไม่สามารถจริงๆleal TextLabel, LabelFromBssSegmentเมื่อคุณมี smth เช่น.bss .lcomm LabelFromBssSegment, 4คุณจะต้องmovl $TextLabel, LabelFromBssSegmentเป็นไม่ได้หรือไม่
JSmyth

@JSmyth: นั่นเป็นเพียงเพราะleaต้องการปลายทางการลงทะเบียน แต่movสามารถมีimm32ต้นทางและปลายทางของหน่วยความจำได้ ข้อ จำกัด นี้ไม่เฉพาะเจาะจงกับแอสเซมเบลอร์ GNU
Peter Cordes

1
นอกจากนี้คำตอบนี้ผิดโดยทั่วไปเนื่องจากคำถามกำลังถามถึงMOV AX, [TABLE-ADDR]ซึ่งเป็นการโหลด ดังนั้นจึงมีความแตกต่างที่สำคัญ คำสั่งที่เทียบเท่าคือmov ax, OFFSET table_addr
Peter Cordes

ลิงค์ตายแล้ว
Ryan1729

10

ขึ้นอยู่กับแอสเซมเบลอร์ที่ใช้เพราะ

mov ax,table_addr

ใน MASM ทำงานเป็นไฟล์

mov ax,word ptr[table_addr]

ดังนั้นมันโหลดไบต์แรกจากและไม่ชดเชยtable_addr table_addrคุณควรใช้แทน

mov ax,offset table_addr

หรือ

lea ax,table_addr

ซึ่งใช้งานได้เหมือนกัน

leaเวอร์ชันยังใช้งานได้ดีหากtable_addrเป็นตัวแปรท้องถิ่นเช่น

some_procedure proc

local table_addr[64]:word

lea ax,table_addr

ขอบคุณมากฉันไม่สามารถทำเครื่องหมายมากกว่าหนึ่งเป็นคำตอบ :(
naveen

5
ความแตกต่างระหว่างคำแนะนำ x86 MOV และ LEA แน่นอนที่สุดไม่ได้ขึ้นอยู่กับแอสเซมเบลอร์
IJ Kennedy

7

ไม่มีคำตอบใดก่อนหน้านี้ที่ทำให้เกิดความสับสนของตัวเองดังนั้นฉันจึงขอเพิ่มคำตอบของฉันเอง

สิ่งที่ผมขาดหายไปก็คือว่าleaการดำเนินงานถือว่าการใช้งานของวงเล็บที่แตกต่างจากวิธีการที่movไม่

ลองนึกถึง C. สมมุติว่าฉันมีอาร์เรย์longที่เรียกarrayว่า ตอนนี้นิพจน์จะarray[i]ทำการ dereference โดยโหลดค่าจากหน่วยความจำตามที่อยู่array + i * sizeof(long)[1]

บนมืออื่น ๆ &array[i]ให้พิจารณาการแสดงออก สิ่งนี้ยังคงมีนิพจน์ย่อยarray[i]แต่ไม่มีการยกเลิกการอ้างอิง! ความหมายของarray[i]มีการเปลี่ยนแปลง ไม่ได้หมายความว่าจะทำการเบี่ยงเบนอีกต่อไป แต่ทำหน้าที่เป็นชนิดของข้อมูลจำเพาะโดยบอก&ว่าเรากำลังมองหาที่อยู่หน่วยความจำใด หากคุณต้องการคุณสามารถคิดอีกวิธีหนึ่งว่า&เป็นการ "ยกเลิก" การอ้างสิทธิ์

เนื่องจากกรณีการใช้งานทั้งสองมีความคล้ายคลึงกันในหลาย ๆ ด้านจึงใช้ไวยากรณ์ร่วมarray[i]กัน แต่การมีอยู่หรือไม่มีการ&เปลี่ยนแปลงวิธีตีความไวยากรณ์นั้น หากไม่มี&มันเป็นการหักล้างและอ่านจากอาร์เรย์ ด้วย&มันไม่ใช่ ค่าarray + i * sizeof(long)ยังคงคำนวณ แต่ก็ไม่ได้ dereferenced

สถานการณ์จะคล้ายกันมากกับและmov leaด้วยmovการ dereference leaเกิดขึ้นที่ไม่ได้เกิดขึ้นกับ แม้จะมีการใช้วงเล็บที่เกิดขึ้นทั้งสองอย่าง ตัวอย่างเช่นmovq (%r8), %r9และleaq (%r8), %r9. ด้วยmovวงเล็บเหล่านี้หมายถึง "dereference"; ด้วยleaพวกเขาไม่ นี้จะคล้ายกับวิธีarray[i]หมายถึงเฉพาะ "dereference" &เมื่อไม่มี

ตัวอย่างเป็นไปตามลำดับ

พิจารณารหัส

movq (%rdi, %rsi, 8), %rbp

นี้โหลดค่าที่ตั้งหน่วยความจำลงในการลงทะเบียน%rdi + %rsi * 8 %rbpนั่นคือ: ได้รับค่าในการลงทะเบียนและความคุ้มค่าในการลงทะเบียน%rdi %rsiคูณหลังด้วย 8 แล้วบวกเข้าไปในอดีต หาค่าที่สถานที่แห่งนี้%rbpและวางไว้ในการลงทะเบียน

รหัสนี้จะสอดคล้องกับสายซีx = array[i];ที่arrayจะกลายเป็น%rdiและiจะกลายเป็น%rsiและจะกลายเป็นx คือความยาวของชนิดข้อมูลที่มีอยู่ในอาร์เรย์%rbp8

ลองพิจารณารหัสที่คล้ายกันที่ใช้lea:

leaq (%rdi, %rsi, 8), %rbp

เช่นเดียวกับการใช้งานที่movqสอดคล้องกับการอ้างอิงการใช้leaqที่นี่สอดคล้องกับการไม่อ้างอิง x = &array[i];บรรทัดนี้สอดคล้องประกอบกับสายซี จำได้ว่า&เปลี่ยนความหมายของarray[i]จากการอ้างอิงเป็นการระบุตำแหน่ง ในทำนองเดียวกันการใช้leaqจะเปลี่ยนความหมายของ(%rdi, %rsi, 8)จากการอ้างอิงเป็นการระบุตำแหน่งที่ตั้ง

ความหมายของบรรทัดของรหัสนี้มีดังนี้: ได้รับค่าในการลงทะเบียนและความคุ้มค่าในการลงทะเบียน%rdi %rsiคูณหลังด้วย 8 แล้วบวกเข้าไปในอดีต %rbpวางค่านี้ลงทะเบียน ไม่มีการโหลดจากหน่วยความจำมีเพียงการคำนวณเลขคณิต [2]

โปรดทราบว่าความแตกต่างเพียงอย่างเดียวระหว่างคำอธิบายของฉันleaqและmovqนั่นคือmovqการหักค่าอ้างอิงและleaqไม่ได้ ในความเป็นจริงในการเขียนleaqคำอธิบายโดยพื้นฐานแล้วฉันจะคัดลอก + วางคำอธิบายจากmovqนั้นจึงลบ "ค้นหาค่าที่ตำแหน่งนี้"

สรุป: movqเทียบกับleaqเป็นเรื่องยุ่งยากเพราะใช้วงเล็บเหมือน(%rsi)และ(%rdi, %rsi, 8)ต่างกัน ในmovq(และคำสั่งอื่น ๆ ทั้งหมดยกเว้นlea) วงเล็บเหล่านี้แสดงถึง dereference ของแท้ในขณะที่leaqไม่มีและเป็นไวยากรณ์ที่สะดวกอย่างแท้จริง


[1] ฉันได้กล่าวว่าเมื่อarrayเป็นอาร์เรย์ของlongนิพจน์โหลดค่าจากที่อยู่array[i] array + i * sizeof(long)นี่เป็นเรื่องจริง แต่มีความละเอียดอ่อนที่ควรแก้ไข ถ้าฉันเขียนรหัส C

long x = array[5];

สิ่งนี้ไม่เหมือนกับการพิมพ์

long x = *(array + 5 * sizeof(long));

ดูเหมือนว่ามันควรจะขึ้นอยู่กับข้อความก่อนหน้าของฉัน แต่มันไม่ใช่

สิ่งที่เกิดขึ้นคือการเพิ่มตัวชี้ C มีเคล็ดลับ ว่าฉันมีตัวชี้ชี้ไปที่ค่าประเภทp Tนิพจน์p + iไม่ได้หมายถึง "ตำแหน่งที่pบวกiไบต์" แต่p + i จริงๆแล้วนิพจน์จะหมายถึง "ตำแหน่งที่pบวกi * sizeof(T)ไบต์"

ความสะดวกในการนี้คือการที่จะได้รับ "ค่าต่อไป" เราก็ต้องมีการเขียนแทนp + 1p + 1 * sizeof(T)

ซึ่งหมายความว่ารหัส C long x = array[5];นั้นเทียบเท่ากับ

long x = *(array + 5)

เพราะ C จะคูณ5ด้วยโดยsizeof(long)อัตโนมัติ

ดังนั้นในบริบทของคำถาม StackOverflow ทั้งหมดนี้เกี่ยวข้องอย่างไร หมายความว่าเมื่อฉันพูดว่า "ที่อยู่array + i * sizeof(long)" ฉันไม่ได้หมายถึงให้ " array + i * sizeof(long)" แปลเป็นนิพจน์ C ฉันกำลังทำการคูณด้วยsizeof(long)ตัวเองเพื่อให้คำตอบของฉันมีความชัดเจนมากขึ้น แต่เข้าใจว่าด้วยเหตุนี้จึงไม่ควรอ่านนิพจน์นี้เป็น C เช่นเดียวกับคณิตศาสตร์ทั่วไปที่ใช้ไวยากรณ์ C

[2] หมายเหตุด้านข้าง: เนื่องจากทั้งหมดleaคือการดำเนินการทางคณิตศาสตร์อาร์กิวเมนต์ของมันจึงไม่จำเป็นต้องอ้างถึงที่อยู่ที่ถูกต้อง ด้วยเหตุนี้จึงมักใช้ในการคำนวณทางคณิตศาสตร์บริสุทธิ์กับค่าที่อาจไม่ได้ตั้งใจให้ถูกอ้างถึง ตัวอย่างเช่นccด้วย-O2การเพิ่มประสิทธิภาพการแปล

long f(long x) {
  return x * 5;
}

ในรายการต่อไปนี้ (ลบบรรทัดที่ไม่เกี่ยวข้องออก):

f:
  leaq (%rdi, %rdi, 4), %rax  # set %rax to %rdi + %rdi * 4
  ret

2
ใช่คำอธิบายที่ดีในรายละเอียดมากกว่าคำตอบอื่น ๆ และใช่&ตัวดำเนินการของ C เป็นตัวเปรียบเทียบที่ดี บางทีควรชี้ให้เห็นว่า LEA เป็นกรณีพิเศษในขณะที่ MOV ก็เหมือนกับคำสั่งอื่น ๆ ที่สามารถใช้หน่วยความจำหรือลงทะเบียนตัวถูกดำเนินการได้ เช่นadd (%rdi), %eaxใช้โหมดกำหนดแอดเดรสเพื่อจัดการกับหน่วยความจำเช่นเดียวกับ MOV ที่เกี่ยวข้อง: การใช้ LEA กับค่าที่ไม่ใช่ที่อยู่ / ตัวชี้? ใช้คำอธิบายเพิ่มเติม: LEA คือวิธีที่คุณสามารถใช้การสนับสนุน HW ของ CPU สำหรับการคำนวณที่อยู่เพื่อทำการคำนวณโดยพลการ
Peter Cordes

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

@PeterCordes ขอบคุณ! ฉันได้เพิ่มประเด็นว่ามันเป็นกรณีพิเศษในคำตอบ
Quelklef

1
@ecm จุดดี; ฉันไม่ได้สังเกตเห็นสิ่งนั้น ฉันเปลี่ยนไปแล้วขอบคุณ! :)
Quelklef

FYI วลีสั้น ๆ ที่ช่วยแก้ปัญหาที่ ecm ชี้ให้เห็น ได้แก่ "ค่าของ %rdi " หรือ "ค่าใน %rdi " "ค่าในทะเบียน%rdi" ของคุณยาว แต่ใช้ได้ดีและบางทีอาจช่วยให้ใครบางคนพยายามทำความเข้าใจกับการลงทะเบียนเทียบกับหน่วยความจำ
Peter Cordes

4

ตามที่ระบุไว้ในคำตอบอื่น ๆ :

  • MOVจะดึงข้อมูลตามที่อยู่ภายในวงเล็บและวางข้อมูลนั้นลงในตัวถูกดำเนินการปลายทาง
  • LEAจะทำการคำนวณที่อยู่ภายในวงเล็บและวางที่อยู่ที่คำนวณนั้นลงในตัวถูกดำเนินการปลายทาง สิ่งนี้เกิดขึ้นโดยไม่ต้องออกไปที่หน่วยความจำและรับข้อมูล งานที่ทำLEAอยู่ในการคำนวณ "ที่อยู่ที่มีผล"

เนื่องจากหน่วยความจำสามารถแก้ไขได้หลายวิธี (ดูตัวอย่างด้านล่าง) LEAบางครั้งจึงใช้เพื่อเพิ่มหรือคูณการลงทะเบียนเข้าด้วยกันโดยไม่ต้องใช้คำสั่งADDหรือMULคำสั่งที่ชัดเจน(หรือเทียบเท่า)

เนื่องจากทุกคนกำลังแสดงตัวอย่างในไวยากรณ์ของ Intel นี่คือบางส่วนในไวยากรณ์ของ AT&T:

MOVL 16(%ebp), %eax       /* put long  at  ebp+16  into eax */
LEAL 16(%ebp), %eax       /* add 16 to ebp and store in eax */

MOVQ (%rdx,%rcx,8), %rax  /* put qword at  rcx*8 + rdx  into rax */
LEAQ (%rdx,%rcx,8), %rax  /* put value of "rcx*8 + rdx" into rax */

MOVW 5(%bp,%si), %ax      /* put word  at  si + bp + 5  into ax */
LEAW 5(%bp,%si), %ax      /* put value of "si + bp + 5" into ax */

MOVQ 16(%rip), %rax       /* put qword at rip + 16 into rax                 */
LEAQ 16(%rip), %rax       /* add 16 to instruction pointer and store in rax */

MOVL label(,1), %eax      /* put long at label into eax            */
LEAL label(,1), %eax      /* put the address of the label into eax */

คุณไม่ต้องการโหมดกำหนดแอดเดรสlea label, %eaxแบบสัมบูรณ์ [disp32]ใช้mov $label, %eaxแทน ใช่มันใช้งานได้ แต่มีประสิทธิภาพน้อยกว่า (รหัสเครื่องใหญ่ขึ้นและทำงานบนหน่วยประมวลผลน้อยลง) เนื่องจากคุณพูดถึง AT&T การใช้ LEA กับค่าที่ไม่ใช่ที่อยู่ / ตัวชี้? ใช้ AT&T และคำตอบของฉันมีตัวอย่างอื่น ๆ ของ AT&T
Peter Cordes

2

โดยพื้นฐานแล้ว ... "ย้ายไปที่ REG ... หลังจากคำนวณแล้ว ... " ดูเหมือนจะดีสำหรับวัตถุประสงค์อื่นเช่นกัน :)

หากคุณลืมไปว่าค่านั้นเป็นตัวชี้ที่คุณสามารถใช้เพื่อเพิ่มประสิทธิภาพ / ลดขนาดโค้ด ...

MOV EBX , 1
MOV ECX , 2

;//with 1 instruction you got result of 2 registers in 3rd one ...
LEA EAX , [EBX+ECX+5]

EAX = 8

เดิมมันจะเป็น:

MOV EAX, EBX
ADD EAX, ECX
ADD EAX, 5

ใช่leaเป็นคำสั่ง shift-and-addที่ใช้การเข้ารหัสและไวยากรณ์ของเครื่องโอเปอแรนด์หน่วยความจำเนื่องจากฮาร์ดแวร์รู้วิธีถอดรหัส ModR / M + SIB + disp0 / 8/32 อยู่แล้ว
Peter Cordes

1

มาทำความเข้าใจกับตัวอย่างนี้

mov eax, [ebx] และ

lea eax, [ebx] สมมติว่าค่าใน ebx คือ 0x400000 จากนั้น mov จะไปที่ที่อยู่ 0x400000 และคัดลอกข้อมูล 4 ไบต์ที่นำเสนอไปยัง eax register ในขณะที่ lea จะคัดลอกที่อยู่ 0x400000 ลงใน eax ดังนั้นหลังจากดำเนินการตามค่าคำสั่งของ eax ในแต่ละกรณีจะเป็น (สมมติว่าในหน่วยความจำ 0x400000 มี 30)

eax = 30 (ในกรณีของ mov) eax = 0x400000 (ในกรณีของ lea) สำหรับคำจำกัดความ mov คัดลอกข้อมูลจาก rm32 ไปยังปลายทาง (mov dest rm32) และ lea (โหลดที่อยู่ที่มีประสิทธิภาพ) จะคัดลอกที่อยู่ไปยังปลายทาง (mov dest rm32 ).


1

MOV สามารถทำสิ่งเดียวกันกับ LEA [label] แต่คำสั่ง MOV มีแอดเดรสที่มีประสิทธิภาพภายในคำสั่งเป็นค่าคงที่ทันที (คำนวณล่วงหน้าโดยแอสเซมเบลอร์) LEA ใช้ PC-สัมพัทธ์ในการคำนวณที่อยู่ที่มีประสิทธิผลระหว่างการดำเนินการตามคำสั่ง


นั่นเป็นความจริงสำหรับโหมด 64 บิตเท่านั้น (ที่ที่อยู่แบบสัมพันธ์กับพีซีเป็นแบบใหม่) ในโหมดอื่น ๆlea [labelเป็นการสิ้นเปลืองไบต์อย่างไร้จุดหมายเมื่อเทียบกับขนาดกะทัดรัดmovกว่าดังนั้นคุณควรระบุเงื่อนไขที่คุณกำลังพูดถึง นอกจากนี้สำหรับแอสเซมเบลอร์บางตัว[label]ไม่ใช่ไวยากรณ์ที่ถูกต้องสำหรับโหมดการกำหนดแอดเดรสแบบสัมพันธ์ RIP แต่ใช่ว่าจะถูกต้อง วิธีโหลดที่อยู่ของฟังก์ชันหรือเลเบลลงในรีจิสเตอร์ใน GNU Assemblerอธิบายรายละเอียดเพิ่มเติม
Peter Cordes

0

LEA (Load Effective Address) คือคำสั่ง shift-and-add เพิ่มเข้าไปใน 8086 เนื่องจากฮาร์ดแวร์อยู่ที่นั่นเพื่อถอดรหัสและคำนวณโหมดการอยู่อาศัย


-1

ความแตกต่างนั้นบอบบาง แต่สำคัญ คำสั่ง MOV คือ 'MOVe' ซึ่งเป็นสำเนาของที่อยู่ที่ป้าย TABLE-ADDR หมายถึง คำสั่ง LEA คือ 'Load Effective Address' ซึ่งเป็นคำสั่งทางอ้อมซึ่งหมายความว่า TABLE-ADDR ชี้ไปยังตำแหน่งหน่วยความจำที่พบแอดเดรสที่จะโหลด

การใช้ LEA อย่างมีประสิทธิภาพนั้นเทียบเท่ากับการใช้พอยน์เตอร์ในภาษาเช่น C ดังนั้นจึงเป็นคำสั่งที่มีประสิทธิภาพ


7
ฉันคิดว่าคำตอบนี้น่าสับสนที่สุด "คำสั่ง LEA คือ 'Load Effective Address' ซึ่งเป็นคำสั่งทางอ้อมซึ่งหมายความว่า TABLE-ADDR ชี้ไปยังตำแหน่งหน่วยความจำที่พบแอดเดรสที่จะโหลด" จริงๆแล้ว LEA จะโหลดที่อยู่ไม่ใช่เนื้อหาของที่อยู่ ฉันคิดว่าผู้ถามต้องมั่นใจว่า MOV และ LEA สามารถทับซ้อนกันได้และทำสิ่งเดียวกันทุกประการในบางสถานการณ์
Bill Forster
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.