ข้อ จำกัด ของ Intel Assembly Syntax เทียบกับ AT&T [ปิด]


89

สำหรับฉันไวยากรณ์ของ Intel นั้นอ่านง่ายกว่ามาก หากฉันท่องไปในฟอเรสต์แอสเซมบลีที่เน้นเฉพาะไวยากรณ์ของ Intel ฉันจะพลาดอะไรไปหรือไม่? มีเหตุผลใดบ้างที่ฉันต้องการเปลี่ยนไปใช้ AT&T (นอกเหนือจากความสามารถในการอ่านชุดประกอบ AT&T ของผู้อื่น) เบาะแสแรกของฉันคือ gdb ใช้ AT&T โดยค่าเริ่มต้น

หากเรื่องนี้สำคัญฉันมุ่งเน้นไปที่แอสเซมบลีความสัมพันธ์เท่านั้นและไวยากรณ์อาจต้องใช้กับ Linux / BSD และภาษา C


11
ฉันชอบคำถามที่ไม่สร้างสรรค์ที่ได้รับคะแนนโหวตมากกว่า 50 ครั้ง
สิ้นสุด

คำตอบ:


81

ไม่มีข้อได้เปรียบที่เหนือกว่าอีกฝ่าย ฉันยอมรับว่าไวยากรณ์ของ Intel นั้นอ่านง่ายกว่ามาก โปรดทราบว่า AFAIK เครื่องมือ GNU ทั้งหมดมีตัวเลือกในการใช้ไวยากรณ์ของ Intel ด้วย

ดูเหมือนว่าคุณสามารถทำให้ GDB ใช้ไวยากรณ์ของ Intel ด้วยสิ่งนี้:

ตั้งค่าการถอดชิ้นส่วน - รส intel

GCC สามารถสร้างไวยากรณ์ของ Intel ด้วย-masm=intel.


18
เช่นกัน echo set dis intel >> ~ / .gdbinit
oevna

9
ไวยากรณ์ของ AT&T อ่านได้น้อยลงอย่างไร ฉันพบว่าคำต่อท้ายขนาดในตัวถูกดำเนินการมีความรัดกุมมากกว่าการมี "dword" มีอย่างอื่นที่ฉันขาดหายไปหรือไม่?
Hawken

54
lea -0x30(%rcx,%rax,8),%eaxเป็น ATT ที่ซับซ้อนสำหรับlea eax,[rcx+rax*8-0x30]. การใช้ + และ * ช่วยได้มากในรูปแบบของ Intel
jørgensen

9
ฉันเห็นว่า "Convolution" ของพวกเขาเท่าเทียมกัน แต่ไม่ปรากฏ: ถ้า ATT ขุ่น Intel ก็มีความคลุมเครือ แม้ว่าเลขคณิต infix จะคุ้นเคยกับนักเรียนพีชคณิตมากกว่า แต่ก็ไม่ชัดเจนจากไวยากรณ์ว่ามีอาร์กิวเมนต์ 4 อาร์กิวเมนต์ในการดำเนินการหรืออาจคูณเพียงหนึ่งในนั้นและไม่ชัดเจนว่าตัวคูณจะต้องเป็น a พลังของ 2.
ข้อผิดพลาด

10
@Hawken ผมพบของ AT & T ต่อท้ายดีกว่าของ Intel "PTR" เพราะคุณมักจะระบุว่าและมันจริงๆช่วยลดปริมาณของความผิดพลาด (อย่างน้อยสำหรับฉัน) เกี่ยวกับส่วนที่เหลือ (เช่นสัญลักษณ์ $ และ%) .. ใช่ .. มันไม่น่าพอใจและนั่นคือประเด็น แต่พวกเขามีข้อได้เปรียบ: ชัดเจนและลดความผิดพลาดอีกครั้ง ฉันจะบอกว่าสิ่งหนึ่งสะดวกสบายสำหรับการอ่าน (Intel) และอย่างที่สองสำหรับการเขียน (AT&T)
MasterMastic

43

ไวยากรณ์หลักสำหรับแอสเซมเบลอร์ GNU (GAS) คือ AT&T ไวยากรณ์ของ Intel เป็นส่วนเสริมที่ค่อนข้างใหม่ x86 แอสเซมบลีในเคอร์เนล Linux อยู่ในไวยากรณ์ AT&T ในโลกของ Linux มันเป็นไวยากรณ์ทั่วไป ในโลก MS ไวยากรณ์ของ Intel เป็นเรื่องปกติมากขึ้น

ส่วนตัวผมเกลียด AT & T ไวยากรณ์ มีแอสเซมเบลอร์ฟรีมากมาย (NASM, YASM) พร้อมกับ GAS ที่รองรับไวยากรณ์ของ Intel ด้วยดังนั้นจึงไม่มีปัญหาใด ๆ ในการทำไวยากรณ์ของ Intel ใน Linux

นอกเหนือจากนั้นมันเป็นเพียงความแตกต่างทางวากยสัมพันธ์ ผลลัพธ์ของทั้งสองจะเป็นรหัสเครื่อง x86 เดียวกัน


25
ตกลงและตกลงกัน. การใช้ไวยากรณ์ของ AT&T ควรเป็นเรื่องที่ผิดมันใช้งานง่ายและน่าเกลียดเหตุใดคุณจึงต้องการนำหน้าทุกหมายเลขและลงทะเบียนด้วย $ และ% และระบุที่อยู่สัมพัทธ์ในสัญกรณ์ SIB แบบย้อนกลับฉันใช้ไวยากรณ์ของ Intel สำหรับ สองปีและยังมองไม่เห็นว่าทำไม AT&T ถึงมีอยู่
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

11
หากคุณจะระบุเป็นตัวหนาอย่างน้อยก็ให้แสดงหลักฐานว่าเหตุใด intel จึงดีกว่ามาก
Hawken

8
@Hawken Haters จะเกลียด
Gunther Piez

8
@Hawken คุณแนะนำว่าเพราะเขาใช้ตัวหนาเขาเลยแสดงความคิดเห็นของเขาตามความเป็นจริงในแบบที่เขาไม่เคยเป็นถ้าเขาปล่อยให้ตัวหนาอยู่คนเดียว? คำถามนี้ได้รับการเชิญชวนให้เกิด "การอภิปราย" ที่นำโดยความคิดเห็นนี้อยู่แล้วโดยสันนิษฐานได้ว่าทำไมถึงปิดตอนนี้!
Elliott

1
แล้วไวยากรณ์ของ Intel สำหรับ ARM ล่ะ?
สิ้นสุด

34

ไม่มีข้อได้เปรียบที่เหนือกว่าอีกฝ่าย ผมไม่เห็นว่าที่ไวยากรณ์ Intel ง่ายมากที่จะอ่านเพราะโดยส่วนตัวแล้วฉันเกลียดไวยากรณ์ Intel โปรดทราบว่า AFAIK เครื่องมือ GNU ทั้งหมดมีตัวเลือกในการใช้ไวยากรณ์ของ Intel ด้วย

at&t noprefix                   intel
mov eax, -4(ebp,edx,4)          mov DWORD PTR[-4 +ebp +edx *4], eax
mov eax, -4(ebp)                mov DWORD PTR[-4 +ebp], eax
mov edx, (ecx)                  mov DWORD PTR[ecx], edx
lea (   ,eax,4), eax            lea eax, DWORD PTR[8 + eax*4]
lea (eax,eax,2), eax            lea eax, DWORD PTR[eax*2+eax]

... และจะซับซ้อนมากขึ้นด้วยคำสั่งที่ซับซ้อนมากขึ้น

'Nuff กล่าวว่า.

ป.ล. : คำตอบนี้มีสาเหตุหลักมาจากการเน้นจุดอ่อน (IMHO) ในคำตอบอื่น ๆ ซึ่งจริงๆแล้วไม่ใช่คำตอบ แต่เป็นความคิดเห็น และแน่นอนว่าคำตอบนี้ในความเป็นจริงเป็นเพียงความเห็นที่ต่ำต้อยของฉัน

PPS: ฉันไม่ได้เกลียดไวยากรณ์ของ Intel ฉันแค่ไม่สนใจ


20
ฉันสับสนชะมัด คุณกำลังหมายความว่าไวยากรณ์ at & t ไม่จำเป็นต้องทำให้ขนาดของคำชัดเจนหรือไม่? เหตุใดคุณจึงคัดลอกตัวอย่างของฉันและเพิ่มขนาดคำและสิ่งที่ไม่มีประโยชน์ PTR เหตุใดคุณจึงเปลี่ยนความแตกต่างของฉันเป็นผลรวมด้วยตัวถูกดำเนินการด้านซ้ายที่เป็นลบ เป็นเพราะนั่นเป็นวิธีเข้ารหัสคำสั่งจริงหรือ? ผู้ใช้แทบไม่ต้องสนใจเรื่องนั้นจริงๆ ในแอสเซมเบลอร์ทุกตัวที่ฉันใช้คุณสามารถละเว้น DWORD PTR ได้เนื่องจากตัวถูกดำเนินการด้านซ้ายเป็น 32 บิตและตัวถูกดำเนินการด้านขวามีวงเล็บเหลี่ยมล้อมรอบ
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

12
ยิ่งไปกว่านั้น IDA / ollydbg ไม่ได้สร้างสิ่งที่เหมือนกับสิ่งที่คุณเขียนดังนั้นฉันค่อนข้างมั่นใจว่าไม่มีปัญหาในการเปลี่ยนจากรหัสเครื่องไปเป็นไวยากรณ์ intel ที่ "ดี" ดังนั้นตัวอย่างของคุณจึงดูเหมือนสร้างขึ้นมาได้สวยและเป็นสิ่งที่ฉันไม่เคยเห็นยกเว้นในการใช้งานแอสเซมเบลอร์หรือตัวแยกชิ้นส่วนที่ไม่สำคัญที่สุด ในทางกลับกันคำสั่ง at & t ที่ฉันเยาะเย้ยมาจากย่อหน้าแรกของการสอนแบบฝึกสอนที่ & t ไวยากรณ์โดยตรง
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

8
ฉันได้ข้อสรุปว่าคุณเป็นเครื่องจักรดังนั้นคุณจึงต้องการไวยากรณ์ที่สะท้อนการเข้ารหัสบิตของคำสั่งโดยตรง (ซึ่งเป็นสิ่งที่ & t ไวยากรณ์ทำ) ฉันยังสงสัยว่าผู้คนรู้สึกถึง 1337 มากขึ้นเมื่อพวกเขาใช้ไวยากรณ์ที่ & t เนื่องจากมันคลุมเครือมากกว่าแม้ว่านั่นจะไม่ใช่ข้อได้เปรียบจริงๆ ...
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

7
@Longpoke ไม่ไวยากรณ์ของ AT&T ไม่จำเป็นต้องทำให้ขนาดของคำชัดเจนหากมีความชัดเจนจากบริบท เช่นเดียวกับ intel: คุณไม่ต้องการSOMEWORD PTR[]ถ้าขนาดตัวถูกดำเนินการชัดเจนจากบริบท แต่คุณจำเป็นต้องใช้ในกรณีที่ต้องย้ายไปยังตำแหน่งหน่วยความจำทันที (ทั้งlจาก AT&T เป็น DWORD PTR จาก Intel) และใช่ตัวอย่างของฉันมีการสร้างไว้ค่อนข้างดี แต่ก็เป็นของคุณ ในกรณีที่คุณยังไม่เห็นสาเหตุ: คุณละทิ้งคำที่ไม่จำเป็นบน Intel แต่มีไว้ใน AT&T คุณเลือกตัวถูกดำเนินการในลักษณะที่สอดคล้องกันใน Intel แต่อย่าทำใน AT&T
Gunther Piez

7
คุณกำลังบอกว่า-4(ebp,edx,4)สิ่งที่ดีกว่า[4*edx+ebp-4]? ฉันพบว่าอย่างหลังใช้งานง่ายกว่า
Calmarius

24

มันเป็น "ภาษาเดียวกัน" ซึ่งรวบรวมลงในรหัสเครื่องเดียวกันมี opcodes เหมือนกัน ฯลฯ ในทางกลับกันหากคุณใช้ GCC เลยคุณอาจต้องการเรียนรู้ไวยากรณ์ของ AT&T เพียงเพราะ ค่าเริ่มต้น - ไม่มีการเปลี่ยนแปลงตัวเลือกคอมไพเลอร์ ฯลฯ เพื่อรับมัน

ฉันก็ตัดฟันด้วย Intel-syntax x86 ASM (บน DOS ด้วย) และพบว่ามันใช้งานง่ายกว่าในตอนแรกเมื่อเปลี่ยนมาใช้ C / UNIX แต่เมื่อคุณเรียนรู้ AT&T มันจะดูง่ายเหมือนกัน

ฉันจะไม่คิดมากขนาดนั้น - มันเป็นเรื่องง่ายที่จะเรียนรู้ AT&T เมื่อคุณรู้จัก Intel และในทางกลับกัน ภาษาจริงยากที่จะเข้ามาในหัวของคุณมากกว่าไวยากรณ์ ดังนั้นโดยรวมแล้วเพียงแค่มุ่งเน้นไปที่หนึ่งแล้วเรียนรู้อีกครั้งเมื่อมันเกิดขึ้น


16
อะไร? เนื่องจาก GCC ใช้ที่ & t โดยค่าเริ่มต้นจึงไม่มีเหตุผลที่จะต้องเรียนรู้ที่ & t ไวยากรณ์ โดยเฉพาะอย่างยิ่งเมื่อคุณสามารถเปลี่ยนไปใช้ไวยากรณ์ของ Intel ที่ใช้งานง่ายขึ้น
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

7
@longpoke การเรียนรู้ไวยากรณ์ intel เพียงเพราะใคร ๆ ก็เรียกมันว่า "ใช้งานง่ายกว่า" ไม่ใช่เหตุผลที่ดีกว่า จริงๆแล้วมันไม่มีเหตุผลเลย
Hawken

1
คุณทั้งคู่ถูกต้องด้วยเหตุผลเดียวกันกับที่ทั้ง Verilog และ VHDL ค้างอยู่
bug

@ ฮอว์เคน: จริง เหตุผลที่แท้จริงในการเรียนรู้ไวยากรณ์ของ Intel คือสิ่งที่คู่มือของ Intel และ AMD ใช้ ไม่มีคู่มืออ้างอิง ISA ที่ใช้ไวยากรณ์ AT&T โดยมีรายละเอียดเหมือนกับคู่มือผู้จำหน่ายเช่นfelixcloutier.com/x86/cmppd (ดึงมาจาก PDF ของ Intel) นอกจากนี้ยังมีข้อมูลผลการดำเนินงานเช่นuops.infoและagner.org/optimize ฉันคิดว่าฉันอ่านว่าผู้จำหน่าย Unix บางรายได้ทำการอ้างอิง AT&T ISA ในบางจุด แต่ตอนนี้มันล้าสมัยไปแล้วและจะไม่ครอบคลุมคำแนะนำ AVX 100% เห็นด้วยกับคำตอบนี้: รหัสเครื่องเดียวกัน, ไวยากรณ์ที่แตกต่างกันสำหรับการแสดงมันไม่มีปัญหา
Peter Cordes

19

เป็นสัญญาณของความเป็นมืออาชีพที่คุณยินดีที่จะปรับเปลี่ยนตามการใช้งาน ไม่มีประโยชน์ที่แท้จริงต่อหนึ่งหรืออื่น ๆ ไวยากรณ์ของ Intel เป็นเรื่องปกติในโลกของ Microsoft AT&T เป็นมาตรฐานใน Linux / Unix เนื่องจากไม่มีข้อได้เปรียบใด ๆ สำหรับคนทั้งสองคนจึงมักจะตราตรึงในสิ่งที่พวกเขาเห็นก่อน ที่กล่าวว่าโปรแกรมเมอร์มืออาชีพยกระดับเหนือสิ่งต่างๆเช่นนั้น ใช้สิ่งที่พวกเขาใช้ในที่ทำงานหรือในโดเมนที่คุณทำงานอยู่


5
แล้วการเป็นผู้ใช้เครื่องมือ "มืออาชีพ" และรู้วิธีที่จะเปลี่ยนแปลงเพื่อให้คุณทำงานได้มากขึ้น +1 สำหรับไวยากรณ์ของ Intel
Jonathon Reinhart

5
แม้ว่าฉันจะชอบไวยากรณ์ของ Intel ด้วย แต่เขาก็มีจุดหนึ่ง - พิจารณาการบำรุงรักษาโค้ด AT&T ที่มีอยู่เช่น ไม่มีอันตรายใด ๆ ในการรู้วิธีการของคุณทั้งสองอย่าง
Elliott

7
แม้ว่าฉันจะสนับสนุนการเรียนรู้ทั้งสองอย่าง แต่ฉันจะเล่น Devil's Advocate และแนะนำว่าคุณสามารถเขียนสคริปต์เป็นไฟล์ * .s ที่แปลงอัตโนมัติเป็นไวยากรณ์ที่คุณเลือกได้
bug

2
เนื่องจากไวยากรณ์ของ intel นั้นอ่านง่ายกว่าไวยากรณ์ของ intel จึงมีข้อได้เปรียบ "lea eax, [eax * 4 + 8]" มีความสามารถในการอ่านวัตถุประสงค์ที่ดีกว่า "leal 8 (,% eax, 4),% eax" มาก
Lucio M. Tato

2
@bug Heh คุณสะกดผิด emacs; D
GDP2

13

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

ที่ & t intel
movl -4 (% ebp,% edx, 4),% eax mov eax, [ebp-4 + edx * 4]
movl -4 (% ebp),% eax mov eax, [ebp-4]
movl (% ecx),% edx mov edx, [ecx]
leal 8 (,% eax, 4),% eax lea eax, [eax * 4 + 8]
leal (% eax,% eax, 2),% eax lea eax, [eax * 2 + eax]

... และจะซับซ้อนมากขึ้นด้วยคำสั่งที่ซับซ้อนมากขึ้น

'Nuff กล่าวว่า.


17
ไม่พูดไม่พอ
Gunther Piez

2
ผู้โพสต์ระบุแล้วว่าพวกเขาชอบไวยากรณ์ของ Intel ดีสำหรับพวกเขา แล้วคุณกำลังพยายามโน้มน้าวใคร?
Hawken

2
@ ฮอว์เคนไม่ใช่แค่ผู้โพสต์เท่านั้นที่จะอ่านคำตอบ
wingerse

ฉันชอบที่เขาพูดถึงตัวอย่างด้วยความยาวคำ โปรดเขียนตัวถูกดำเนินการหน่วยความจำเป็นไบต์เดี่ยวหรือแบบสั้น
Ajay Brahmakshatriya

2

ภาษาแอสเซมบลีแรกของฉันคือ MIPS ซึ่งฉันสังเกตเห็นว่าคล้ายกับไวยากรณ์ของ ATT มาก ดังนั้นฉันจึงชอบไวยากรณ์ ATT แต่มันไม่สำคัญตราบเท่าที่คุณสามารถอ่านได้


3
แอสเซมบลี MIPS คล้ายกับไวยากรณ์ของ AT&T ในรูปแบบแอดเดรสของคำสั่ง load / store เท่านั้น แต่ MIPS มีโหมดการกำหนดแอดเดรสแบบง่ายเพียง 1 โหมดสำหรับการโหลด / จัดเก็บในขณะที่ Intel มีอีกมากมายซึ่งทำให้สิ่งนี้ซับซ้อนมากขึ้น พิจารณาlea -0x30(%rcx,%rax,8),%eaxและlea eax,[rcx+rax*8-0x30]jørgensenที่โพสต์ไว้ด้านบน และต่างจาก AT&T ตรงที่ MIPS ยังคงใช้รูปแบบปลายทางเป็นอันดับแรกเหมือนกับที่อื่น ๆ ทั้งหมด นอกจากนี้หมายเลข MIPS ไม่จำเป็นต้องนำหน้าด้วย $ และการลงทะเบียนชื่อใน MIPS นั้นสั้นดังนั้นจึงไม่อึดอัดมากที่จะมี% เหมือน AT&T
phuclv
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.