Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何“理解”(手动解释)用NASM for Linux编写的小型二进制可执行文件_Assembly_Nasm_Executable_Binary Data - Fatal编程技术网

Assembly 如何“理解”(手动解释)用NASM for Linux编写的小型二进制可执行文件

Assembly 如何“理解”(手动解释)用NASM for Linux编写的小型二进制可执行文件,assembly,nasm,executable,binary-data,Assembly,Nasm,Executable,Binary Data,最近我开始学习NASM,我想深入了解编译器、虚拟机和计算机通常如何工作的理论。我编写了一个小而简单的NASM程序,只是为了观察它在使用NASM编译器构建后创建的二进制代码 ASM代码如下所示: section .data c: db 420 section .text global _start: _start: mov ecx, 1337 mov eax,

最近我开始学习NASM,我想深入了解编译器、虚拟机和计算机通常如何工作的理论。我编写了一个小而简单的NASM程序,只是为了观察它在使用NASM编译器构建后创建的二进制代码

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-0x4000e3上的89指令意味着将寄存器移到另一个寄存器中。但令我困惑的是,指令行上的第二个字节并不是我所期望的。我怎么解释呢?过载部分有问题吗


谢谢大家抽出时间,请原谅我英语不好。每次我都尽力去改进它

您知道,您不需要对其进行反向工程,因为官方手册中有很好的文档记录,对吗?:见表2-2。《英特尔64和IA-32体系结构软件开发人员手册》第2卷2A、2B和2C:指令集参考,A-Z中包含ModR/M字节的32位寻址形式

请注意,x86寄存器并没有按照您期望的顺序编号。无论出于何种原因,顺序为:eax、ecx、edx、ebx、esp、ebp、esi、edi

在第二个字节(称为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

您知道,您不需要对其进行反向工程,因为它在官方手册中有很好的文档记录,对吗见表2-2。《英特尔64和IA-32体系结构软件开发人员手册》第2卷2A、2B和2C:指令集参考,A-Z中包含ModR/M字节的32位寻址形式

请注意,x86寄存器并没有按照您期望的顺序编号。无论出于何种原因,顺序为:eax、ecx、edx、ebx、esp、ebp、esi、edi

在第二个字节(称为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
您可能希望使用objdump-M intel-D file.o来获得更类似于原始源代码的内容,除非您确实对gas语法感到好奇。您可能希望使用objdump-M intel-D file.o来获得更类似于原始源代码的内容,除非您确实对gas语法感到好奇。