2017-03-03 75 views
1

最近我开始学习NASM,我想深入了解编译器,虚拟机和计算机通常工作的理论。我写了一个小而简单的NASM程序,只是为了观察它在用NASM编译器构建之后创建的二进制代码。如何“理解”(手动解释)用NAS编写的微型二进制可执行文件

的ASM代码是在这里:

section .data 
      c: db 420 

    section .text 
      global _start: 
      _start: 
      mov ecx, 1337 

      mov eax, eax 
      mov eax, ebx 
      mov eax, ecx 
      mov eax, edx 
      mov eax, ebp 
      mov eax, esp 

      mov ebx, eax 
      mov ebx, ebx 
      mov ebx, ecx 
      mov ebx, edx 
      mov ebx, ebp 
      mov ebx, esp 

      mov ecx, eax 
      mov ecx, ebx 
      mov ecx, ecx 
      mov ecx, edx 
      mov ecx, ebp 
      mov ecx, esp 

      mov edx, eax 
      mov edx, ebx 
      mov edx, ecx 
      mov edx, edx 
      mov edx, ebp 
      mov edx, esp 


      ; exit 
      mov eax, 1 
      mov ebx, 2 
      int 80h 

所以基本上,我在这里只是每移动注册到所有其他寄存器。我知道输出将会有'mov'命令重载,所以带有寄存器的mov看起来不同于带有寄存器和常量的mov。该计划的上述明明很简单太objdump的:

./program:  file format elf64-x86-64 
    Disassembly of section .text: 

    00000000004000b0 <.text>: 
    4000b0: b9 39 05 00 00   mov $0x539,%ecx 
    4000b5: 89 c0     mov %eax,%eax 
    4000b7: 89 d8     mov %ebx,%eax 
    4000b9: 89 c8     mov %ecx,%eax 
    4000bb: 89 d0     mov %edx,%eax 
    4000bd: 89 e8     mov %ebp,%eax 
    4000bf: 89 e0     mov %esp,%eax 

    4000c1: 89 c3     mov %eax,%ebx 
    4000c3: 89 db     mov %ebx,%ebx 
    4000c5: 89 cb     mov %ecx,%ebx 
    4000c7: 89 d3     mov %edx,%ebx 
    4000c9: 89 eb     mov %ebp,%ebx 
    4000cb: 89 e3     mov %esp,%ebx 

    4000cd: 89 c1     mov %eax,%ecx 
    4000cf: 89 d9     mov %ebx,%ecx 
    4000d1: 89 c9     mov %ecx,%ecx 
    4000d3: 89 d1     mov %edx,%ecx 
    4000d5: 89 e9     mov %ebp,%ecx 
    4000d7: 89 e1     mov %esp,%ecx 

    4000d9: 89 c2     mov %eax,%edx 
    4000db: 89 da     mov %ebx,%edx 
    4000dd: 89 ca     mov %ecx,%edx 
    4000df: 89 d2     mov %edx,%edx 
    4000e1: 89 ea     mov %ebp,%edx 
    4000e3: 89 e2     mov %esp,%edx 


    4000e5: b8 01 00 00 00   mov $0x1,%eax 
    4000ea: bb 02 00 00 00   mov $0x2,%ebx 
    4000ef: cd 80     int $0x80 

我们可以看到,在“0x4000b5” 89指令 - “0x4000e3”是指移动注册到其他寄存器。但令我困惑的是,指令行上的第二个字节并不是我所认为的。我如何解释这一点? “超载”部分有问题吗?

谢谢大家,我的坏英语请原谅。我尽力改进它,每次我都可以! :)

+0

您可能想要使用'objdump -M intel -D file.o'来获得更类似于原始源代码的东西,除非您真的对gas语法感到好奇。 – Ped7g

回答

4

您知道您不需要对此进行反向工程,因为它在官方手册中有详细记录,对不对? :)见表2-2。具有ModR/M字节的32位寻址格式 in 英特尔®64和IA-32架构软件开发人员手册第2卷(2A,2B & 2C):指令集参考,A-Z

请注意,x86寄存器没有按照您期望的顺序编号。顺序,无论出于何种原因,就是:eaxecxedxebxespebpesiedi

在称为modr/m的第二个字节中,位#0-2和#3-5用于编码寄存器操作数。这在十六进制中并不是很明显,但会以八进制显示。例如:

211 300 mov %eax,%eax ; move from register #0 to #0 
211 330 mov %ebx,%eax ; move from register #3 to #0 
211 313 mov %ecx,%ebx ; move from register #1 to #3 
相关问题