【问题标题】:NASM & GDB: losing first instructionNASM 和 GDB:丢失第一条指令
【发布时间】:2011-05-13 23:54:30
【问题描述】:

我正在学习汇编程序,发现以下一些令人惊讶的地方。我基本上是从互联网上的某个地方复制了一些 hello world 代码

section .text
    global  _start

_start:
    mov edx,len
    mov ecx,msg
    mov ebx,1
    mov eax,4
    int 0x80        ; interrupt for calling kernel

    mov eax,1
    int 0x80

section .data

msg db  'Hello, world!',0xa
len equ $ - msg

我用 nasm -f elf -g hello.asm, ld hellow.o -o hello 编译并链接它。如果我现在将它加载到 gdb 中,我可以列出代码并运行它就好了。如果我在第一条 mov 指令上设置断点,程序不会停在那里。在我得到的结果文件上运行 ndisasm (ndisasm -b32 hello)(我认为相关的部分):

0000007D  0000              add [eax],al
0000007F  00BA0E000000      add [edx+0xe],bh
00000085  B9A0900408        mov ecx,0x80490a0
0000008A  BB01000000        mov ebx,0x1
0000008F  B804000000        mov eax,0x4
00000094  CD80              int 0x80
00000096  B801000000        mov eax,0x1
0000009B  CD80              int 0x80

所以指令没有出现。

我非常感谢有关正在发生的事情的提示,或者去哪里了解正在发生的事情。

【问题讨论】:

    标签: gdb nasm


    【解决方案1】:

    您的指令在反汇编中没有正确显示的原因只是它开始反汇编的位置以及指令如何落下的对齐问题。因为 x86 有可变长度指令,反汇编器需要知道一个入口点。正确的列表更像是:

    00000080  BA0E000000      mov edx,0xe ; I think
    00000085  B9A0900408      mov ecx,0x80490a0
    ...
    

    真正的问题在于 gdb 看起来,可能与您如何设置断点有关(另外,我不记得 gdb 在第一条指令之前是否在中断时阻塞,我必须检查一下)。

    【讨论】:

    • 确实,我通过向 ndisasm 添加“同步点”找到了这些说明:ndisasm -b32 -s0X80 hello。然后按照您的建议对指令进行解码。我假设我的二进制格式包含起点是 80 的信息,但是 readelf 建议 _start 是在 08048080,其他以 80 结尾的似乎与我无关。
    • @kasterma IIRC 可执行文件的开头实际上是 linux/386 上的内存地址 0x08048000
    • 如果我使用 gcc 进行链接,我会得到一个更大的可执行文件,但我可以在第一条指令上放置一个有效的断点。
    猜你喜欢
    • 2012-05-16
    • 2011-11-19
    • 2012-07-23
    • 2018-06-01
    • 2021-12-28
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多