คำถามติดแท็ก assembly

คำถามการเขียนโปรแกรมแอสเซมบลีภาษา (asm) โปรดมั่นใจว่าแท็กด้วยโปรเซสเซอร์และ / หรือชุดคำสั่งที่คุณใช้รวมถึงแอสเซมเบลอร์ คำเตือน: สำหรับแอสเซมบลี. NET ให้ใช้แท็ก [.net-assembly] แทน สำหรับ Java ASM ให้ใช้แท็ก [java-bytecode-asm] แทน

6
ฉันจะแยกรหัสเครื่อง 16 บิต x86 ดิบได้อย่างไร
ฉันต้องการแยกชิ้นส่วน MBR (512 ไบต์แรก) ของดิสก์ x86 ที่สามารถบู๊ตได้ที่ฉันมี ฉันคัดลอก MBR ไปยังไฟล์โดยใช้ dd if=/dev/my-device of=mbr bs=512 count=1 ข้อเสนอแนะสำหรับยูทิลิตี้ Linux ที่สามารถแยกไฟล์ได้mbrหรือไม่?
91 linux  assembly  x86  x86-16  mbr 


4
ถ้าการลงทะเบียนเร็วมากทำไมเราไม่มีมากกว่านี้ล่ะ?
ใน 32 บิตเรามีการลงทะเบียน "วัตถุประสงค์ทั่วไป" 8 รายการ ด้วย 64 บิตจำนวนเงินจะเพิ่มขึ้นเป็นสองเท่า แต่ดูเหมือนว่าจะไม่ขึ้นอยู่กับการเปลี่ยนแปลง 64 บิตเอง ตอนนี้ถ้าการลงทะเบียนเร็วมาก (ไม่มีการเข้าถึงหน่วยความจำ) ทำไมถึงไม่มีการลงทะเบียนมากกว่านี้? ผู้สร้าง CPU ไม่ควรลงทะเบียนใน CPU ให้มากที่สุดเท่าที่จะทำได้หรือไม่? อะไรคือข้อ จำกัด เชิงตรรกะที่ทำให้เรามีเพียงจำนวนเงินที่เรามี?

7
ข้อ จำกัด ของ Intel Assembly Syntax เทียบกับ AT&T [ปิด]
ตามที่กล่าวมาในปัจจุบันคำถามนี้ไม่เหมาะสำหรับรูปแบบถาม & ตอบของเรา เราคาดหวังว่าคำตอบจะได้รับการสนับสนุนจากข้อเท็จจริงการอ้างอิงหรือความเชี่ยวชาญ แต่คำถามนี้อาจก่อให้เกิดการถกเถียงโต้แย้งการสำรวจความคิดเห็นหรือการอภิปรายเพิ่มเติม หากคุณรู้สึกว่าคำถามนี้สามารถปรับปรุงได้และอาจเปิดขึ้นมาใหม่ได้โปรดไปที่ศูนย์ช่วยเหลือเพื่อรับคำแนะนำ ปิดให้บริการใน8 ปีที่ผ่านมา สำหรับฉันไวยากรณ์ของ Intel นั้นอ่านง่ายกว่ามาก หากฉันท่องไปในฟอเรสต์แอสเซมบลีที่เน้นเฉพาะไวยากรณ์ของ Intel ฉันจะพลาดอะไรไปหรือไม่? มีเหตุผลใดบ้างที่ฉันต้องการเปลี่ยนไปใช้ AT&T (นอกเหนือจากความสามารถในการอ่านชุดประกอบ AT&T ของผู้อื่น) เบาะแสแรกของฉันคือ gdb ใช้ AT&T โดยค่าเริ่มต้น หากเรื่องนี้สำคัญฉันมุ่งเน้นไปที่แอสเซมบลีความสัมพันธ์เท่านั้นและไวยากรณ์อาจต้องใช้กับ Linux / BSD และภาษา C
89 linux  assembly  x86  att  bsd 

3
การใช้ gdb กับโค้ดแอสเซมบลีขั้นตอนเดียวที่นอกเหนือจากปฏิบัติการที่ระบุทำให้เกิดข้อผิดพลาด“ ไม่พบขอบเขตของฟังก์ชันปัจจุบัน”
ฉันอยู่นอกเป้าหมายปฏิบัติการของ gdb และฉันไม่มีสแต็กที่ตรงกับเป้าหมายนั้นด้วยซ้ำ ฉันต้องการทำทีละขั้นตอนเพื่อที่ฉันจะได้ตรวจสอบว่าเกิดอะไรขึ้นในรหัสแอสเซมบลีของฉันเพราะฉันไม่ใช่ผู้เชี่ยวชาญในการประกอบ x86 น่าเสียดายที่ gdb ปฏิเสธที่จะทำการดีบักระดับแอสเซมบลีอย่างง่ายนี้ ช่วยให้ฉันสามารถตั้งค่าและหยุดบนเบรกพอยต์ที่เหมาะสมได้ แต่ทันทีที่ฉันพยายามทำทีละขั้นตอนเป็นต้นไป gdb รายงานข้อผิดพลาด "ไม่พบขอบเขตของฟังก์ชันปัจจุบัน" และ EIP จะไม่เปลี่ยนแปลง รายละเอียดเพิ่มเติม: รหัสเครื่องถูกสร้างขึ้นโดยคำสั่ง gcc asm และฉันคัดลอกไปยังตำแหน่งหน่วยความจำเคอร์เนลที่มันทำงานจากเอาต์พุตของ objdump -d ฉันไม่รังเกียจวิธีง่ายๆในการใช้ตัวโหลดเพื่อโหลดรหัสออบเจ็กต์ของฉันไปยังที่อยู่ที่ย้ายตำแหน่ง แต่จำไว้ว่าการโหลดจะต้องทำในโมดูลเคอร์เนล ฉันคิดว่าอีกทางเลือกหนึ่งคือการสร้างโมดูลเคอร์เนลปลอมหรือไฟล์ข้อมูลการดีบักเพื่อมอบให้กับ gdb เพื่อทำให้เชื่อว่าพื้นที่นี้อยู่ในโค้ดโปรแกรม gdb ทำงานได้ดีบนเคอร์เนลที่รันได้เอง (สำหรับผู้ที่ต้องการทราบจริงๆฉันกำลังแทรกโค้ดที่รันไทม์ลงในพื้นที่ข้อมูลเคอร์เนลของลินุกซ์ภายใน VMware VM และทำการดีบักจาก gdb รีโมตดีบักเคอร์เนลผ่าน gdb ในตัวของ VMware Workstation หมายเหตุฉันไม่ได้เขียนเคอร์เนล หาประโยชน์ฉันเป็นนักศึกษาระดับบัณฑิตศึกษาด้านความปลอดภัยที่เขียนต้นแบบ) (ฉันสามารถตั้งค่าเบรกพอยต์สำหรับแต่ละคำสั่งภายในแอสเซมบลีของฉันได้ซึ่งใช้งานได้ แต่จะค่อนข้างลำบากหลังจากนั้นสักครู่เนื่องจากขนาดของคำแนะนำการประกอบ x86 จะแตกต่างกันไปและตำแหน่งของการประกอบจะเปลี่ยนไปทุกครั้งที่รีบูต)


30
ทำไมคุณถึงตั้งโปรแกรมในการประกอบ? [ปิด]
ปิด . คำถามนี้เป็นคำถามความคิดเห็นตาม ขณะนี้ยังไม่ยอมรับคำตอบ ต้องการปรับปรุงคำถามนี้หรือไม่ อัปเดตคำถามเพื่อให้สามารถตอบได้ด้วยข้อเท็จจริงและการอ้างอิงโดยแก้ไขโพสต์นี้ ปิดให้บริการ1 ปีที่ผ่านมา ปรับปรุงคำถามนี้ ฉันมีคำถามสำหรับแฮกเกอร์ระดับต่ำที่ไม่ยอมใครง่ายๆทั้งหมดที่นั่น ฉันเจอประโยคนี้ในบล็อก ฉันไม่คิดว่าแหล่งที่มามีความสำคัญ (เป็นเรื่องที่ฮากถ้าคุณสนใจจริงๆ) เพราะมันดูเหมือนจะเป็นคำพูดทั่วไป ตัวอย่างเช่นเกม 3 มิติสมัยใหม่จำนวนมากมีเอ็นจิ้นหลักประสิทธิภาพสูงที่เขียนด้วย C ++ และ Assembly เท่าที่แอสเซมบลีจะดำเนินไป - คือโค้ดที่เขียนขึ้นในแอสเซมบลีเนื่องจากคุณไม่ต้องการให้คอมไพเลอร์ปล่อยคำสั่งพิเศษหรือใช้ไบต์มากเกินไปหรือคุณใช้อัลกอริทึมที่ดีกว่าซึ่งคุณไม่สามารถแสดงใน C (หรือไม่สามารถแสดงออกได้โดยไม่ต้อง คอมไพเลอร์รวบรวมพวกเขาขึ้น)? ฉันเข้าใจดีว่าการเข้าใจสิ่งที่มีระดับต่ำเป็นสิ่งสำคัญ ฉันแค่อยากเข้าใจว่าทำไมต้องใช้โปรแกรมในแอสเซมบลีหลังจากที่คุณเข้าใจแล้ว

2
“ ตัวแทน; นพ;” ค่าเฉลี่ยในการประกอบ x86? เหมือนกับคำสั่ง "หยุดชั่วคราว" หรือไม่
อะไรrep; nopหมายถึง? เหมือนกับการpauseเรียนการสอนหรือไม่? มันเหมือนกับrep nop(ไม่มีอัฒภาค) หรือไม่? nopคำสั่งง่ายๆแตกต่างกันอย่างไร? มันทำงานแตกต่างกันในโปรเซสเซอร์ AMD และ Intel หรือไม่? (โบนัส) เอกสารอย่างเป็นทางการสำหรับคำแนะนำเหล่านี้อยู่ที่ไหน? แรงจูงใจสำหรับคำถามนี้ หลังจากการสนทนาในความคิดเห็นของคำถามอื่นฉันตระหนักว่าฉันไม่รู้ว่าrep; nop;หมายความว่าอย่างไรในการประกอบ x86 (หรือ x86-64) และฉันไม่พบคำอธิบายที่ดีในเว็บ ฉันรู้ว่านั่นrepคือคำนำหน้าซึ่งหมายถึง"ทำซ้ำคำสั่งcxครั้งต่อไป" (หรืออย่างน้อยก็คือในแอสเซมบลี x86 16 บิตเก่า) ตามนี้ตารางสรุปที่วิกิพีเดียดูเหมือนว่าrepสามารถนำมาใช้เฉพาะกับmovs, stos, cmps, lods, scas( แต่บางทีข้อ จำกัด นี้จะถูกลบออกในโปรเซสเซอร์ใหม่กว่า) ดังนั้นฉันคิดว่าrep nop(ไม่ลำไส้ใหญ่กึ่ง) จะทำซ้ำnopการดำเนินการcxครั้ง อย่างไรก็ตามหลังจากค้นหาเพิ่มเติมฉันก็ยิ่งสับสน ดูเหมือนว่าrep; nopและpause แมปกับ opcode เดียวกันและpauseมีพฤติกรรมที่แตกต่างจากเพียงnopเล็กน้อย จดหมายเก่าบางฉบับจากปี 2548กล่าวถึงสิ่งที่แตกต่างกัน: “ พยายามอย่าเผาผลาญพลังงานมากเกินไป” "เทียบเท่ากับ 'nop' เพียงแค่เข้ารหัส …

4
เหตุใดจึงสามารถส่ง T * ในการลงทะเบียน แต่ unique_ptr <T> ไม่สามารถทำได้?
ฉันกำลังดูการสนทนาของ Chandler Carruth ใน CppCon 2019: ไม่มี Abstractions Zero-Cost ในนั้นเขาให้ตัวอย่างของวิธีการที่เขารู้สึกประหลาดใจเพียงเท่าใดค่าใช้จ่ายที่คุณเกิดขึ้นโดยใช้std::unique_ptr&lt;int&gt;มากกว่าint*; ส่วนนั้นเริ่มต้นที่เวลา 17:25 น คุณสามารถดูผลการรวบรวมตัวอย่างของคู่ของเขา (godbolt.org) - เพื่อเป็นพยานว่าที่จริงดูเหมือนว่าคอมไพเลอร์ไม่เต็มใจที่จะผ่านค่า unique_ptr - ซึ่งในความเป็นจริงในบรรทัดล่างคือ เพียงที่อยู่ - ภายในการลงทะเบียนเท่านั้นในหน่วยความจำแบบตรง หนึ่งในประเด็นที่นายคาร์รั ธ ทำเวลาประมาณ 27:00 น. คือ C ++ ABI ต้องการพารามิเตอร์ตามค่า (บางส่วน แต่ไม่ใช่ทั้งหมดบางทีอาจเป็น - ประเภทที่ไม่ใช่แบบดั้งเดิมหรือไม่ใช่ประเภทที่ไม่สามารถแก้ไขได้) จะถูกส่งผ่านในหน่วยความจำ มากกว่าภายในทะเบียน คำถามของฉัน: นี่เป็นข้อกำหนดของ ABI ในบางแพลตฟอร์มหรือไม่ (อันไหน) หรือบางทีมันอาจเป็นเพียงการมองโลกในแง่ร้ายในบางสถานการณ์? เหตุใด ABI จึงเป็นเช่นนั้น นั่นคือถ้าเขตข้อมูลของโครงสร้าง / …

1
คำแนะนำ x86 ต้องการการเข้ารหัสของตัวเองรวมถึงข้อโต้แย้งทั้งหมดของพวกเขาที่จะปรากฏในหน่วยความจำในเวลาเดียวกันหรือไม่?
ฉันพยายามที่จะคิดออกว่าเป็นไปได้ในการเรียกใช้ Linux VM ซึ่ง RAM ได้รับการสนับสนุนโดยเพจฟิสิคัลเดียวหรือไม่ หากต้องการจำลองสิ่งนี้ฉันได้แก้ไขตัวจัดการข้อผิดพลาดหน้าซ้อนใน KVM เพื่อลบบิตปัจจุบันออกจากรายการตารางหน้าที่ซ้อนกัน (NPT) ทั้งหมดยกเว้นรายการที่สอดคล้องกับข้อบกพร่องของเพจที่ประมวลผลในปัจจุบัน ในขณะที่พยายามเริ่มต้นแขกลินุกซ์ฉันสังเกตว่าคำแนะนำการประกอบที่ใช้ตัวถูกดำเนินการหน่วยความจำเช่น add [rbp+0x820DDA], ebp นำไปสู่การวนรอบข้อบกพร่องของหน้าจนกว่าฉันจะคืนค่าบิตปัจจุบันสำหรับหน้าที่มีคำสั่งเช่นเดียวกับหน้าอ้างอิงในตัวถูกดำเนินการ (ในตัวอย่างนี้ [rbp+0x820DDA] ) ฉันสงสัยว่าทำไมในกรณีนี้ ซีพียูไม่ควรเข้าถึงหน้าหน่วยความจำตามลำดับหรือไม่เช่นอ่านคำสั่งก่อนจากนั้นจึงเข้าถึงตัวถูกดำเนินการหน่วยความจำ หรือ x86 ต้องการหน้าคำสั่งเช่นเดียวกับหน้าตัวถูกดำเนินการทั้งหมดในเวลาเดียวกันหรือไม่? ฉันกำลังทดสอบกับ AMD Zen 1

1
เหตุใดการเริ่มต้นรวม GCC ของอาร์เรย์จึงเติมเต็มทั้งศูนย์ด้วยก่อนรวมถึงองค์ประกอบที่ไม่ใช่ศูนย์
ทำไม gcc เติมทั้งอาร์เรย์ด้วยศูนย์แทนที่จะเป็นจำนวนเต็ม 96 เท่านั้นที่เหลือ? initializers ที่ไม่ใช่ศูนย์ทั้งหมดอยู่ที่จุดเริ่มต้นของอาร์เรย์ void *sink; void bar() { int a[100]{1,2,3,4}; sink = a; // a escapes the function asm("":::"memory"); // and compiler memory barrier // forces the compiler to materialize a[] in memory instead of optimizing away } MinGW8.1 และ gcc9.2 สร้าง asm เช่นนี้ ( Godbolt …

1
ทำไม GCC ไม่สามารถสันนิษฐานได้ว่า std :: vector :: size จะไม่เปลี่ยนแปลงในลูปนี้
ฉันอ้างว่าเป็นเพื่อนร่วมงานที่if (i &lt; input.size() - 1) print(0);จะได้รับการเพิ่มประสิทธิภาพในวงนี้เพื่อที่input.size()จะไม่ได้อ่านทุกครั้ง แต่มันกลับกลายเป็นว่านี่ไม่ใช่กรณี! void print(int x) { std::cout &lt;&lt; x &lt;&lt; std::endl; } void print_list(const std::vector&lt;int&gt;&amp; input) { int i = 0; for (size_t i = 0; i &lt; input.size(); i++) { print(input[i]); if (i &lt; input.size() - 1) print(0); } } ตามCompiler Explorerพร้อมตัวเลือก gcc …
14 c++  gcc  assembly 

1
สำเนาของรหัสเครื่องที่แน่นอนทำงานช้ากว่าฟังก์ชั่นเดิม 50%
ฉันทำการทดลองเล็กน้อยกับการใช้งานจาก RAM และหน่วยความจำแฟลชในระบบฝังตัว สำหรับการสร้างต้นแบบอย่างรวดเร็วและการทดสอบฉันกำลังใช้ Arduino Due (SAM3X8E ARM Cortex-M3) เท่าที่ฉันเห็น Arduino runtime และ bootloader ไม่ควรสร้างความแตกต่างที่นี่ นี่คือปัญหา: ฉันมีฟังก์ชั่น ( Calc ) ซึ่งเขียนใน ARM Thumb Assembly calcคำนวณตัวเลขและส่งคืน (&gt; 1s รันไทม์สำหรับอินพุตที่กำหนด) ตอนนี้ฉันแยกรหัสเครื่องประกอบของฟังก์ชั่นนั้นด้วยตนเองและวางเป็นไบต์ดิบลงในฟังก์ชั่นอื่น ฟังก์ชั่นทั้งสองได้รับการยืนยันว่าอยู่ในหน่วยความจำแฟลช (ที่อยู่ 0x80149 และ 0x8017D ติดกัน) สิ่งนี้ได้รับการยืนยันผ่านการถอดแยกชิ้นส่วนและการตรวจสอบรันไทม์ void setup() { Serial.begin(115200); timeFnc(calc); timeFnc(calc2); } void timeFnc(int (*functionPtr)(void)) { unsigned long time1 …

1
ทำไมคอมไพเลอร์ยืนยันที่จะใช้การลงทะเบียนที่บันทึกไว้ที่นี่?
พิจารณารหัส C นี้: void foo(void); long bar(long x) { foo(); return x; } เมื่อฉันรวบรวมใน GCC 9.3 ด้วย-O3หรือ-Osฉันได้รับ: bar: push r12 mov r12, rdi call foo mov rax, r12 pop r12 ret เอาท์พุทจากเสียงดังกราวเหมือนกันยกเว้นการเลือกrbxแทนr12การลงทะเบียน callee- บันทึก อย่างไรก็ตามฉันต้องการ / คาดหวังว่าจะเห็นชุดประกอบที่มีลักษณะดังนี้: bar: push rdi call foo pop rax ret ในภาษาอังกฤษนี่คือสิ่งที่ฉันเห็นว่าเกิดขึ้น: ผลักดันค่าเก่าของการลงทะเบียนที่บันทึกไว้แบบสลี ย้ายxไปยังการลงทะเบียนที่ถูกบันทึกด้วย callee โทร …
10 c  gcc  assembly  clang  x86-64 

1
เหตุใด DOS จึงตั้งค่า SP register เป็น 0xFFFE หลังจากโหลดไฟล์. COM
ในหน้า wikpedia เกี่ยวกับไฟล์. COM https://en.wikipedia.org/wiki/COM_fileจะอ่าน: ไฟล์. COM ใน DOS ตั้งค่าเซกเมนต์ x86 ทั้งหมดที่ลงทะเบียนเป็นค่าเดียวกันและ SP (ตัวชี้สแต็ค) ลงทะเบียนเป็น 0xFFFE ดังนั้นสแต็กจะเริ่มต้นที่ด้านบนสุดของเซ็กเมนต์หน่วยความจำและทำงานจากที่นั่น แต่นี่จะเป็นการตั้งค่าสแต็กให้เริ่มหนึ่งคำด้านล่างด้านบนของกลุ่ม เมื่อกดค่าบนสแต็ก CPU จะลด SP เป็น 0xFFFC และเก็บค่าไว้ที่นั่น สาเหตุที่ DOS ไม่ตั้งค่า SP เป็น 0 แทนคืออะไร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.