Assembly 使用寄存器和表偏移量的绝对调用

Assembly 使用寄存器和表偏移量的绝对调用,assembly,x86,nasm,Assembly,X86,Nasm,为了练习偏移量、寻址、表格等,我用NASM编写了以下程序 t_addr: dw rout1-@, rout2-@ @ equ $ _start: mov esi, rout1 call esi call _start_reloc _start_reloc: pop ebp sub ebp, _start_reloc-@

为了练习偏移量、寻址、表格等,我用NASM编写了以下程序

t_addr:
        dw      rout1-@, rout2-@

@       equ     $
_start:
        mov     esi, rout1
        call    esi

        call    _start_reloc
_start_reloc:
        pop     ebp
        sub     ebp, _start_reloc-@

        xor     eax, eax
        add     eax, 1
        sal     eax, 1

        lea     esi, [ebp+t_addr-@]
        mov     ax, word [esi+eax]
        add     eax, ebp
        call    eax
        ret

rout1:
        mov     eax, 0
        ret

rout2:
        xor     eax, eax
        ret
尽管\u startlabel之后的前两条指令按其应运行,并将控制权转移到rout1函数,但当我尝试使用表中的偏移量访问rout2函数时,在GDB中,我查看call eax指令前的eax值,执行调用时包含rout2的地址,我得到分段错误,EIP加载0x00000001。为什么


p、 s:我使用32位linux。

我看到的第一个问题是,当您输入_start\u reloc时,您会弹出ebp。当该函数结束并重新调用时,eip将获取堆栈上的值。通常情况下,这将是ebp,但由于您弹出了它,现在eip有一个随机值。用mov ebp、[esp]或pop ebp代替pop ebp,然后按ebp

谢谢!你的回答很有帮助,现在我明白了GDB中nexti和stepi的区别:)@user466825:不客气!:)电脑有时很烦人P