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

Assembly 如何在裸机上获取平面二进制代码地址?,assembly,x86,gdb,disassembly,bare-metal,Assembly,X86,Gdb,Disassembly,Bare Metal,我有一个汇编文件的源代码,我想在将其转换为二进制文件后将其反汇编,以便在正确的位置设置断点 我试着用下面的命令使用objdump(我使用的是ORG语句,这就是为什么我使用--adjust vma) 这在某种程度上是可行的,但它混淆了指令,例如在我的源代码中 pop bx inc bx ; bx is used in the internal copy_sector_byte loop cmp cx, 512 jne .copy_sector_byte

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

我试着用下面的命令使用
objdump
(我使用的是ORG语句,这就是为什么我使用
--adjust vma

这在某种程度上是可行的,但它混淆了指令,例如在我的源代码中

    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 e7
jne
指令上的二进制代码

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


我不熟悉组装。谢谢

您可以让NASM在组装时制作一个“列表”:
NASM-l foo.lst foo.asm
(默认的平面二进制输出模式,默认的输出文件名为
foo
)。或者让它用
nasm-l/dev/stdout foo.asm | less
将列表写入stdout,如果您只想动态查看它的话

但不幸的是,输出不遵守
org
指令,它仍然是相对于图像库的:

     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"

或者正如@MichaelPetch在评论中所建议的那样:

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

我将停止使用二进制文件作为链接器脚本的输出类型。只需让它生成ELF可执行文件,然后使用
objcopy
将ELF可执行文件转换为二进制文件即可。二进制文件在远程计算机上运行,ELF文件在调试器中使用

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

我要说的是,GDB和QEMU在调试16位实模式代码时很棘手,因为GDB对实模式中的段:偏移寻址没有真正的理解

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


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

您似乎正在将16位代码分解为32位代码。您应该能够只使用
objdump-Mintel,i8086-bbinary-adjust vma=0x0500-dfoo.o|less
<代码>-Mi8086将反汇编为16位代码。或使用NDISAM或向您的汇编程序索取清单。@MichaelPetch我的代码既有32位代码,也有16位代码,有什么建议吗?我个人会生成一个ELF版本的内核文件和一个二进制版本。ELF版本可以包含调试信息,而二进制版本将被执行。我将停止使用
binary
作为链接器脚本的输出类型。只需让它生成ELF可执行文件,然后使用
objcopy
将ELF可执行文件转换为二进制文件即可。二进制文件在远程计算机上运行,ELF文件在调试器中使用。调试器可以使用ELF文件获取符号信息,这是最容易调试的。我要说的是,GDB和QEMU在调试16位实模式代码时很棘手,因为GDB对实模式中的段:偏移寻址没有真正的理解。
     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"