如何在裸机上获取平坦的二进制代码地址?

时间:2019-07-13 12:48:52

标签: assembly operating-system gdb bare-metal

我有一个汇编文件的源代码,在将其转换为二进制文件后,我想对其进行反汇编,以便可以在正确的位置设置断点。

我尝试通过以下命令使用objdump(我正在使用ORG语句,这就是为什么我使用--adjust-vma的原因)

objdump -Mintel,i386 -b binary --adjust-vma=0x0500 -D foo.o -m i386 | less

在某种程度上可以工作,但是会混淆指令,例如在我拥有的源代码中

    pop bx
    inc bx  ; bx is used in the internal copy_sector_byte loop
    cmp cx, 512
    jne .copy_sector_byte  
    pop bx 

但已翻译为

 5a9:   5b                      pop    ebx
 5aa:   43                      inc    ebx
 5ab:   81 f9 00 02 75 e7       cmp    ecx,0xe7750200
 5b1:   5b                      pop    ebx

请注意,75 e7jne指令上的二进制代码。

我可以告诉objectdump以某种方式使用我拥有的源文件(或使用其他程序)吗?您有什么建议?

我是新来的。谢谢

1 个答案:

答案 0 :(得分:1)

您可以使NASM组装时进行“列出”:test.cpp:30:24: error: type/value mismatch at argument 1 in template parameter list for 'template<class T> class XYZ' XYZ < Foo <A> :: Bar <A> > Foo <A> :: gx () ^ test.cpp:30:24: note: expected a type, got '(Foo<A>::Bar < <expression error>)' test.cpp:30:26: error: expected unqualified-id before '>' token XYZ < Foo <A> :: Bar <A> > Foo <A> :: gx () (具有默认的平面二进制输出模式和默认的输出文件名nasm -l foo.lst foo.asm)。或者,如果您只是想即时查看,可以用foo将清单写到stdout。

但是不幸的是,输出不遵守nasm -l /dev/stdout foo.asm | less指令,它仍然相对于图像库:

org

或如@MichaelPetch在注释中建议的那样:

  

我个人将生成内核文件的ELF版本和二进制版本。 ELF版本可以包含调试信息,而二进制版本将执行。

     

我将停止 1 org 0x7c00 2 3 00000000 31C0 xor ax,ax 4 00000002 8ED8 mov ds, ax 5 6 00000004 686869 push "hi" 7 00000007 C706[0D00]7879 mov word [var], 'xy' 8 9 0000000D 68656C6C6F var: db "hello" 二进制作为链接描述文件的输出类型。只需让它生成ELF可执行文件,然后使用using将ELF可执行文件转换为二进制文件即可。二进制文件在远程计算机上运行,​​ELF文件在调试器中使用。

     

调试器可以使用ELF文件获取符号信息,这是最容易调试的信息。

     

我会说GDB和QEMU在调试16位实模式代码时非常棘手,因为GDB对实模式下的segment:offset寻址没有真正的了解。

BOCHS具有一个内置的调试器,它可以理解分段,并且具有用于解析IDT和GDT的内置命令,而不仅仅是转储原始字节。

Michael过去曾建议BOCHS用于调试切换到保护模式和/或长模式的引导加载程序。