ฉันทำแบบนี้หลายครั้งและยังคงทำเช่นนี้ต่อไป ในกรณีที่เป้าหมายหลักของคุณคือการอ่านและไม่เขียนแอสเซมเบลอร์ฉันคิดว่านี่ใช้ได้
เขียนตัวถอดประกอบของคุณเอง ไม่ใช่เพื่อจุดประสงค์ในการถอดชิ้นส่วนที่ยิ่งใหญ่ที่สุดต่อไปอันนี้เหมาะสำหรับคุณโดยเฉพาะ เป้าหมายคือการเรียนรู้ชุดคำสั่ง ไม่ว่าฉันจะเรียนรู้แอสเซมเบลอร์บนแพลตฟอร์มใหม่จำแอสเซมเบลอร์สำหรับแพลตฟอร์มที่ฉันเคยรู้จัก เริ่มต้นด้วยโค้ดเพียงไม่กี่บรรทัดตัวอย่างเช่นการเพิ่มรีจิสเตอร์และการปิงปองระหว่างการแยกส่วนเอาต์พุตไบนารีและเพิ่มคำแนะนำที่ซับซ้อนมากขึ้นในด้านอินพุตคุณ:
1) เรียนรู้ชุดคำสั่งสำหรับโปรเซสเซอร์เฉพาะ
2) เรียนรู้ความแตกต่างของวิธีการเขียนโค้ดในการประกอบสำหรับโปรเซสเซอร์ดังกล่าวเพื่อให้คุณสามารถกระดิกบิต opcode ทุกคำสั่งได้
3) คุณเรียนรู้ชุดคำสั่งได้ดีกว่าวิศวกรส่วนใหญ่ที่ใช้ชุดคำสั่งนั้นในการหาเลี้ยงชีพ
ในกรณีของคุณมีปัญหาสองสามข้อโดยปกติฉันแนะนำให้ใช้ชุดคำสั่ง ARM ในวันนี้มีผลิตภัณฑ์ที่ใช้ ARM มากกว่าที่จัดส่งในวันนี้มากกว่าเครื่องอื่น ๆ (รวมคอมพิวเตอร์ x86) แต่ความเป็นไปได้ที่คุณจะใช้ ARM ในขณะนี้และไม่รู้จักแอสเซมเบลอร์เพียงพอสำหรับการเขียนโค้ดเริ่มต้นหรือกิจวัตรอื่น ๆ ที่รู้ว่า ARM อาจช่วยหรือไม่ช่วยในสิ่งที่คุณกำลังพยายามทำ เหตุผลที่สองและสำคัญกว่าสำหรับ ARM อันดับแรกเป็นเพราะความยาวคำสั่งมีขนาดคงที่และจัดแนว การแยกชิ้นส่วนคำสั่งที่มีความยาวผันแปรเช่น x86 อาจเป็นฝันร้ายในโครงการแรกของคุณและเป้าหมายคือเพื่อเรียนรู้ชุดคำสั่งที่จะไม่สร้างโครงการวิจัย Third ARM เป็นชุดคำสั่งที่ทำได้ดีมีการสร้างรีจิสเตอร์ให้เท่ากันและไม่มีความแตกต่างพิเศษของแต่ละบุคคล
ดังนั้นคุณจะต้องหาโปรเซสเซอร์ที่คุณต้องการเริ่มต้นด้วย ฉันขอแนะนำ msp430 หรือ ARM ก่อนจากนั้น ARM ก่อนหรือสองจากนั้นจึงเกิดความโกลาหลของ x86 ไม่ว่าจะใช้แพลตฟอร์มใดแพลตฟอร์มใดก็ตามที่คุ้มค่าจะมีเอกสารข้อมูลหรือคู่มืออ้างอิงโปรแกรมเมอร์ที่ไม่ต้องเสียค่าใช้จ่ายจากผู้ขายซึ่งรวมถึงชุดคำสั่งตลอดจนการเข้ารหัสของ opcodes (บิตและไบต์ของภาษาเครื่อง) เพื่อจุดประสงค์ในการเรียนรู้ว่าคอมไพเลอร์ทำอะไรและวิธีการเขียนโค้ดที่คอมไพลเลอร์ไม่ต้องดิ้นรนมันเป็นการดีที่จะรู้ชุดคำสั่งสองสามชุดและดูว่าโค้ดระดับสูงเดียวกันนั้นถูกนำไปใช้อย่างไรในแต่ละชุดคำสั่งกับคอมไพเลอร์แต่ละตัวด้วยการปรับให้เหมาะสม การตั้งค่า. คุณไม่ต้องการเพิ่มประสิทธิภาพโค้ดของคุณเพียงเพื่อพบว่าคุณได้ทำให้ดีขึ้นสำหรับคอมไพเลอร์ / แพลตฟอร์มเดียว แต่แย่กว่าสำหรับทุก ๆ
โอ้สำหรับการแยกชุดคำสั่งความยาวตัวแปรแทนที่จะเริ่มต้นที่จุดเริ่มต้นและแยกส่วนคำสี่ไบต์ทุกคำแบบเชิงเส้นผ่านหน่วยความจำเช่นเดียวกับที่คุณทำกับ ARM หรือทุกๆสองไบต์เช่น msp430 (msp430 มีคำแนะนำความยาวผันแปรได้ แต่คุณยังสามารถทำได้โดย ไปตามเส้นตรงผ่านหน่วยความจำถ้าคุณเริ่มต้นที่จุดเข้าจากตารางเวกเตอร์ขัดจังหวะ) สำหรับความยาวผันแปรคุณต้องการค้นหาจุดเข้าตามตารางเวกเตอร์หรือความรู้เกี่ยวกับวิธีที่โปรเซสเซอร์บู๊ตและปฏิบัติตามโค้ดตามลำดับการดำเนินการ คุณต้องถอดรหัสแต่ละคำสั่งอย่างสมบูรณ์เพื่อให้ทราบจำนวนไบต์ที่ใช้ถ้าคำสั่งนั้นไม่ใช่สาขาที่ไม่มีเงื่อนไขถือว่าไบต์ถัดไปหลังจากคำสั่งนั้นเป็นคำสั่งอื่น คุณต้องจัดเก็บที่อยู่สาขาที่เป็นไปได้ทั้งหมดด้วยและถือว่าเป็นที่อยู่ไบต์เริ่มต้นสำหรับคำแนะนำเพิ่มเติม ครั้งหนึ่งที่ฉันประสบความสำเร็จฉันทำหลายครั้งผ่านไบนารี เริ่มต้นที่จุดเริ่มต้นฉันทำเครื่องหมายว่าไบต์นั้นเป็นจุดเริ่มต้นของคำสั่งจากนั้นถอดรหัสเชิงเส้นผ่านหน่วยความจำจนกระทั่งกดปุ่มกิ่งที่ไม่มีเงื่อนไข เป้าหมายสาขาทั้งหมดถูกแท็กเป็นที่อยู่เริ่มต้นของคำสั่ง ฉันทำการส่งผ่านไบนารีหลายครั้งจนกว่าฉันจะไม่พบเป้าหมายสาขาใหม่ หากเมื่อใดก็ตามที่คุณพบว่าคำสั่ง 3 ไบต์ แต่ด้วยเหตุผลบางประการคุณได้ติดแท็กไบต์ที่สองเป็นจุดเริ่มต้นของคำสั่งแสดงว่าคุณมีปัญหา หากโค้ดถูกสร้างขึ้นโดยคอมไพเลอร์ระดับสูงสิ่งนี้ไม่ควรเกิดขึ้นเว้นแต่คอมไพเลอร์จะทำสิ่งที่ชั่วร้าย หากโค้ดมีแอสเซมเบลอร์ที่เขียนด้วยมือ (เช่นเกมอาร์เคดรุ่นเก่า) เป็นไปได้มากทีเดียวที่จะมีกิ่งก้านตามเงื่อนไขที่ไม่สามารถเกิดขึ้นได้เช่น r0 = 0 ตามด้วยการกระโดดหากไม่ใช่ศูนย์ คุณอาจต้องแก้ไขสิ่งเหล่านั้นออกจากไบนารีเพื่อดำเนินการต่อ สำหรับเป้าหมายเฉพาะของคุณซึ่งฉันคิดว่าจะอยู่ที่ x86 ฉันไม่คิดว่าคุณจะมีปัญหา
ฉันแนะนำเครื่องมือ gcc mingw32 เป็นวิธีง่ายๆในการใช้เครื่องมือ gcc บน Windows ถ้า x86 เป็นเป้าหมายของคุณ ถ้าไม่ใช่ mingw32 plus msys เป็นแพลตฟอร์มที่ยอดเยี่ยมสำหรับการสร้าง cross compiler จาก binutils และ gcc source (โดยทั่วไปค่อนข้างง่าย) mingw32 มีข้อดีกว่า cygwin เช่นโปรแกรมที่เร็วกว่าอย่างมากและคุณหลีกเลี่ยงนรก dll ของ cygwin gcc และ binutils จะช่วยให้คุณสามารถเขียนใน C หรือแอสเซมเบลอร์และถอดรหัสของคุณออกและมีหน้าเว็บมากกว่าที่คุณจะอ่านได้ซึ่งแสดงให้คุณเห็นวิธีการทำอย่างใดอย่างหนึ่งหรือทั้งหมดในสาม หากคุณกำลังจะทำสิ่งนี้กับชุดคำสั่งที่มีความยาวผันแปรฉันขอแนะนำให้คุณใช้ชุดเครื่องมือที่มีตัวถอดชิ้นส่วน ตัวอย่างเช่นการถอดชิ้นส่วนของบุคคลที่สามสำหรับ x86 จะเป็นความท้าทายในการใช้งานเนื่องจากคุณไม่มีทางรู้ว่ามีการถอดชิ้นส่วนอย่างถูกต้องหรือไม่ บางส่วนก็ขึ้นอยู่กับระบบปฏิบัติการเช่นกันเป้าหมายคือการรวบรวมโมดูลเป็นรูปแบบไบนารีที่มีข้อมูลการทำเครื่องหมายคำแนะนำจากข้อมูลเพื่อให้ตัวแยกชิ้นส่วนสามารถทำงานได้แม่นยำยิ่งขึ้น ทางเลือกอื่นของคุณสำหรับเป้าหมายหลักนี้คือการมีเครื่องมือที่สามารถรวบรวมโดยตรงไปยังแอสเซมเบลอร์สำหรับการตรวจสอบของคุณจากนั้นหวังว่าเมื่อรวบรวมเป็นรูปแบบไบนารีจะสร้างคำสั่งเดียวกัน
คำตอบสั้น ๆ (สั้นกว่าเล็กน้อย) สำหรับคำถามของคุณ เขียนตัวแยกชิ้นส่วนเพื่อเรียนรู้ชุดคำสั่ง ฉันจะเริ่มต้นด้วยสิ่งที่ยากและง่ายต่อการเรียนรู้เช่น ARM เมื่อคุณทราบชุดคำสั่งหนึ่งชุดคำสั่งอื่น ๆ จะง่ายต่อการหยิบขึ้นมาบ่อยครั้งในเวลาไม่กี่ชั่วโมงโดยชุดคำสั่งที่สามคุณสามารถเริ่มเขียนโค้ดได้เกือบจะในทันทีโดยใช้แผ่นข้อมูล / คู่มืออ้างอิงสำหรับไวยากรณ์ โปรเซสเซอร์ทั้งหมดที่ควรค่าแก่การใช้มีแผ่นข้อมูลหรือคู่มืออ้างอิงที่อธิบายคำแนะนำลงไปจนถึงบิตและไบต์ของ opcodes เรียนรู้โปรเซสเซอร์ RISC เช่น ARM และ CISC เช่น x86 เพียงพอที่จะเข้าใจถึงความแตกต่างเช่นต้องผ่านการลงทะเบียนสำหรับทุกสิ่งหรือสามารถดำเนินการโดยตรงบนหน่วยความจำโดยมีการลงทะเบียนน้อยลงหรือไม่มีเลย คำสั่งตัวถูกดำเนินการสามคำกับสองคำสั่ง ฯลฯ ในขณะที่คุณปรับแต่งโค้ดระดับสูงของคุณ คอมไพล์สำหรับโปรเซสเซอร์มากกว่าหนึ่งตัวและเปรียบเทียบเอาต์พุต สิ่งที่สำคัญที่สุดที่คุณจะได้เรียนรู้คือไม่ว่าโค้ดระดับสูงจะเขียนคุณภาพของคอมไพเลอร์ได้ดีเพียงใดและตัวเลือกการเพิ่มประสิทธิภาพที่สร้างความแตกต่างอย่างมากในคำแนะนำจริง ฉันแนะนำ llvm และ gcc (พร้อม binutils) ไม่ผลิตรหัสที่ดีแต่เป็นหลายแพลตฟอร์มและหลายเป้าหมายและทั้งสองมีเครื่องมือเพิ่มประสิทธิภาพ และทั้งสองอย่างนั้นฟรีและคุณสามารถสร้างคอมไพเลอร์ข้ามจากแหล่งสำหรับโปรเซสเซอร์เป้าหมายต่างๆได้อย่างง่ายดาย