Operating system x86_64 nasm跳转到错误的位置
我正在编写枚举PCI总线的代码,但发现每个设备上的循环的jz语句跳到了错误的位置(甚至没有标签)。每次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
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-felf64
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
在您预期的情况下,条件是否为真?此外,您在与添加
相同的行上有一个标签,但是您有一条注释,说明代码跳转到测试
之前的行(即跳转到有标签的添加)。但是,在文本中,您声称代码跳转到没有标签的指令。这是非常不一致的,而且似乎你从数据中得出了错误的结论和/或描述了错误的东西。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
在您预期的情况下,条件是否为真?此外,您在与添加
相同的行上有一个标签,但是您有一条注释,说明代码跳转到测试
之前的行(即跳转到有标签的添加)。但是,在文本中,您声称代码跳转到没有标签的指令。这是非常不一致的,而且似乎你从数据中得出了虚假的结论和/或描述了错误的东西。