代码之家  ›  专栏  ›  技术社区  ›  Greg Nisbet

OS X上的Nasm用子程序替换int 0x80

  •  1
  • Greg Nisbet  · 技术社区  · 6 年前

    我试图理解在OS X机器上调用子例程时会发生什么(因为这就是我面前的情况)。我正在使用 nasm 版本0.98.40。

    我读了一些主要针对其他平台的教程,并注意到其中有一些有定义

    _syscall:
        int 0x80
        ret
    

    所以,我尝试了一个简单的hello-world,有没有这个子程序,但在其他方面完全相同。

    我很难理解为什么 call 在这种情况下,调用子例程并不“等同于”直接使用其主体。我认为我没有干扰系统调用所需的任何寄存器。

    以下是两个部件文件。

    ; without_subr.asm
    section .text
    global start
    
    start:
        push dword msg.len
        push dword msg
        push dword 1
        mov eax,4
        sub esp,4
        int 0x80
    
        add esp,16
    
        push dword 0
        mov  eax, 1
        sub  esp, 12
        int 0x80
    
    section .data
    
    msg:    db 'Hello, world!',10
    msg.len:   equ $ - msg
    

    使用子程序:

    ; with_subr.asm
    section .text
    global start
    
    
    _syscall:
        int 0x80
        ret
    
    start:
        push dword msg.len
        push dword msg
        push dword 1
        mov eax,4
        sub esp,4
        call _syscall
    
        add esp,16
    
        push dword 0
        mov  eax, 1
        sub  esp, 12
        int 0x80
    
    section .data
    
    msg:    db 'Hello, world!',10
    msg.len:   equ $ - msg
    

    当我装配、连接和运行时 without_subr.asm 一切正常:

    $ nasm -f macho without_subr.asm 
    $ ld -o without_subr without_subr.o
    $ ./without_subr 
    Hello, world!
    

    然而 with_subr.asm 不生成任何内容并异常退出

    $ nasm -f macho with_subr.asm 
    $ ld -o with_subr with_subr.o
    $ ./with_subr 
    Exit 1
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   user149341 user149341    6 年前

    当你 call 作为一个子例程,返回地址被推送到堆栈上。堆栈上的额外值将保留 push 在错误的地方预先安装。