Operating system x86_64 nasm跳转到错误的位置

Operating system x86_64 nasm跳转到错误的位置,operating-system,nasm,x86-64,Operating System,Nasm,X86 64,我正在编写枚举PCI总线的代码,但发现每个设备上的循环的jz语句跳到了错误的位置(甚至没有标签)。每次cmp ax,0xffff不相等时都应该调用寄存器函数,这应该不止一次。它只会被呼叫一次 register: ; eax = edi = config offset of the function mov dx, ADDR_PRT add eax, 0x08 in eax, dx shr eax, 16

我正在编写枚举PCI总线的代码,但发现每个设备上的循环的jz语句跳到了错误的位置(甚至没有标签)。每次
cmp ax,0xffff
不相等时都应该调用寄存器函数,这应该不止一次。它只会被呼叫一次

register:                               ; eax = edi = config offset of the function
    mov dx, ADDR_PRT
    add eax, 0x08
    in eax, dx
    shr eax, 16
    mov dx, ax
    call checkpoint
    mov eax, edi
rmsd:   cmp dx, 0x0601                  ; mass storage devices
    je ahci_register                ; register an AHCI controller
    ret                             ; couldn't find it, ignore it


pci_init:
    mov edi, 0x80000000
ilp0:   mov rax, rdi
    mov dx, ADDR_PRT
    out dx, eax
    mov dx, DATA_PRT
    in eax, dx
    cmp ax, 0xffff
    je ilp0c0
    push rdi
    mov rax, rdi
    call register
    pop rdi
ilp0c0: add rdi, 0x100
    test edi, 0xff000000            ; code jupms to the line before this
    jz ilp0
    ret

代码作为PE文件进行组装,然后使用lld链接进行链接,并使用EFI运行。

nasm-felf642.14.02版可以很好地组装该代码,并使用针对mov rax,rdi指令的正确分支位移。(我用对象文件上的
objdump-drwC-Mintel
进行了检查)。所以这不是一个简单的问题。(我为丢失的标签/符号添加了虚拟定义。显示NASM 2.13.03也可以工作,尽管NASM的asm输出对于asm来说有点蹩脚)是不是在运行之前覆盖了您的机器代码,改变了分支位移?我想不出应该覆盖它的任何内容,但我注意到了整个工具链,以防万一。你有没有检查过最终二进制文件的反汇编,以防在你的工具链中发生奇怪的事情?在你单步走的时候,还是在跳转到错误的地址之后?你确定是jz ilp0本身将你发送到那里,而不是像ret这样的返回地址出于某种原因指向那里的指令吗?最后一个二进制文件的分解显示它跳到了正确的位置。我调用了一个checkpoint函数来确定跳转的位置。如果检查点位于
add rdi,0x100
行之后,则只会多次调用检查点。那么,为什么您认为
ret
之前的
jz ilp0
会跳转到
test
add
指令,而不是
cmp ax,-1
/
je
在您预期的情况下,条件是否为真?此外,您在与
添加
相同的行上有一个标签,但是您有一条注释,说明代码跳转到
测试
之前的行(即跳转到有标签的添加)。但是,在文本中,您声称代码跳转到没有标签的指令。这是非常不一致的,而且似乎你从数据中得出了错误的结论和/或描述了错误的东西。
nasm-felf64
version 2.14.02很好地汇编了该代码,具有针对
mov-rax,rdi
指令的正确分支位移。(我用对象文件上的
objdump-drwC-Mintel
进行了检查)。所以这不是一个简单的问题。(我为丢失的标签/符号添加了虚拟定义。显示NASM 2.13.03也可以工作,尽管NASM的asm输出对于asm来说有点蹩脚)是不是在运行之前覆盖了您的机器代码,改变了分支位移?我想不出应该覆盖它的任何内容,但我注意到了整个工具链,以防万一。你有没有检查过最终二进制文件的反汇编,以防在你的工具链中发生奇怪的事情?在你单步走的时候,还是在跳转到错误的地址之后?你确定是jz ilp0本身将你发送到那里,而不是像ret这样的返回地址出于某种原因指向那里的指令吗?最后一个二进制文件的分解显示它跳到了正确的位置。我调用了一个checkpoint函数来确定跳转的位置。如果检查点位于
add rdi,0x100
行之后,则只会多次调用检查点。那么,为什么您认为
ret
之前的
jz ilp0
会跳转到
test
add
指令,而不是
cmp ax,-1
/
je
在您预期的情况下,条件是否为真?此外,您在与
添加
相同的行上有一个标签,但是您有一条注释,说明代码跳转到
测试
之前的行(即跳转到有标签的添加)。但是,在文本中,您声称代码跳转到没有标签的指令。这是非常不一致的,而且似乎你从数据中得出了虚假的结论和/或描述了错误的东西。