Linux 用汇编语言访问errno.h

Linux 用汇编语言访问errno.h,linux,assembly,error-handling,x86,system-calls,Linux,Assembly,Error Handling,X86,System Calls,我想访问汇编语言中errno.h中存在的errno,以便处理写函数调用的错误。为此,我在汇编语言中找到了调用_error的地方,但它抛出的错误如下: ExitNewShell.asm:71: error: symbol `_error' undefined ExitNewShell.asm:85: error: symbol `_error' undefined ExitNewShell.asm:98: error: symbol `_error' undefined ExitNewShell.

我想访问汇编语言中errno.h中存在的errno,以便处理写函数调用的错误。为此,我在汇编语言中找到了调用_error的地方,但它抛出的错误如下:

ExitNewShell.asm:71: error: symbol `_error' undefined
ExitNewShell.asm:85: error: symbol `_error' undefined
ExitNewShell.asm:98: error: symbol `_error' undefined
ExitNewShell.asm:111: error: symbol `_error' undefined
ExitNewShell.asm:124: error: symbol `_error' undefined
ExitNewShell.asm:137: error: symbol `_error' undefined
ExitNewShell.asm:150: error: symbol `_error' undefined
ExitNewShell.asm:163: error: symbol `_error' undefined
ExitNewShell.asm:176: error: symbol `_error' undefined
我的汇编代码:ExitNewShell.asm

[SECTION .text]

global _start


_start:

        jmp ender

        starter:

        xor eax, eax    ;clean up the registers
        xor ebx, ebx
        xor edx, edx
        xor ecx, ecx

        mov al, 4       ;syscall write
        mov bl, 1       ;stdout is 1
        pop ecx         ;get the address of the string from the stack
        mov dl, 11       ;length of the string
        int 0x80
    cmp eax,0xffffffff
    jne exit
    call _error
    mov eax,[eax]
    cmp eax,0xb
    jne callOff2
    mov dl,14 
    lea ecx,[msg1]
    mov bl,1
    mov al,4
    int 0x80
    jmp exit


    callOff2:

    call _error
    mov eax,[eax]
    cmp eax,0xb
    jne callOff3
    mov dl,14 
    lea ecx,[msg2]
    mov bl,1
    mov al,4
    int 0x80
    jmp exit

    callOff3:

    call _error
    mov eax,[eax]
    cmp eax,0xb
    jne callOff4
    mov dl,14 
    lea ecx,[msg3]
    mov bl,1
    mov al,4
    int 0x80
    jmp exit

    callOff4:

    call _error
    mov eax,[eax]
    cmp eax,0xb
    jne callOff5
    mov dl,14 
    lea ecx,[msg4]
    mov bl,1
    mov al,4
    int 0x80
    jmp exit

    callOff5:

    call _error
    mov eax,[eax]
    cmp eax,0xb
    jne callOff6
    mov dl,14 
    lea ecx,[msg5]
    mov bl,1
    mov al,4
    int 0x80
    jmp exit

    callOff6:

    call _error
    mov eax,[eax]
    cmp eax,0xb
    jne callOff7
    mov dl,14 
    lea ecx,[msg6]
    mov bl,1
    mov al,4
    int 0x80
    jmp exit

    callOff7:

    call _error
    mov eax,[eax]
    cmp eax,0xb
    jne callOff8
    mov dl,14 
    lea ecx,[msg7]
    mov bl,1
    mov al,4
    int 0x80
    jmp exit

    callOff8:

    call _error
    mov eax,[eax]
    cmp eax,0xb
    jne callOff9
    mov dl,14 
    lea ecx,[msg8]
    mov bl,1
    mov al,4
    int 0x80
    jmp exit

    callOff9:

    call _error
    mov eax,[eax]
    cmp eax,0xb
    jne exit
    mov dl,14 
    lea ecx,[msg9]
    mov bl,1
    mov al,4
    int 0x80
    jmp exit

    exit:
        xor eax, eax
        mov al, 1       ;exit the shellcode
        xor ebx,ebx
        int 0x80

        ender:
        call starter    ;put the address of the string on the stack
        db 'Hello World',0xa

[SECTION .data]

msg1 db 'ERROR - EAGAIN',0
msg2 db 'ERROR - EBADF',0
msg3 db 'ERROR - EPIPE',0
msg4 db 'ERROR - EFAULT',0
msg5 db 'ERROR - EFBIG',0
msg6 db 'ERROR - EINTR',0
msg7 db 'ERROR - EINVAL',0
msg8 db 'ERROR - EIO',0
msg9 db 'ERROR - ENOSPC',0
如何使用汇编语言访问errno?

  • 您正在使用手工编写的汇编代码进行x86 Linux系统调用
  • 如果系统调用失败,则条件
    (无符号长)eax>0xfffff000
    将为真,而
    -(有符号长)eax
    将为错误代码。
    • 在伪C代码中:
      if(-4095
      • 您正在使用手工编写的汇编代码进行x86 Linux系统调用
      • 如果系统调用失败,则条件
        (无符号长)eax>0xfffff000
        将为真,而
        -(有符号长)eax
        将为错误代码。

        • 在伪C代码中:
          如果(-4095
          errno
          只是一个全局
          int
          变量,那么您可以像访问任何其他全局变量一样访问它。@PaulR:在汇编代码中也可以?不包括任何头文件?您必须将其声明为extern,并链接到所需的库(可能是
          libc
          )。正如@MIchael所说,将
          errno
          (或
          \u errno
          )声明为extern,并链接到
          libc
          (我想你已经这么做了)。@Jester:如果涉及多个线程,你的回答可能是相关的。OP正在尝试用一个线程做一些非常简单的事情(隐式)线程。
          errno
          只是一个全局
          int
          变量,因此您可以像访问任何其他全局变量一样访问它。@PaulR:在汇编代码中也可以?不包括任何头文件?您必须将其声明为extern,并链接到所需的库(可能是
          libc
          )。正如@MIchael所说,声明
          errno
          (或
          \u errno
          )作为extern并链接到
          libc
          (我想你已经在这样做了)。@Jester:如果涉及多个线程,你的回答可能是相关的。OP正在尝试用一个(隐式)线程做一些非常简单的事情。 $ gdbdis /lib/libc.so.6 mmap64 0x4ef952a0 : push %ebp 0x4ef952a1 : push %ebx 0x4ef952a2 : push %esi 0x4ef952a3 : push %edi 0x4ef952a4 : mov 0x28(%esp),%edx 0x4ef952a8 : mov 0x2c(%esp),%ecx 0x4ef952ac : test $0xfff,%edx 0x4ef952b2 : jne 0x4ef952eb 0x4ef952b4 : shrd $0xc,%ecx,%edx 0x4ef952b8 : shr $0xc,%ecx 0x4ef952bb : jne 0x4ef952eb 0x4ef952bd : mov %edx,%ebp 0x4ef952bf : mov 0x14(%esp),%ebx 0x4ef952c3 : mov 0x18(%esp),%ecx 0x4ef952c7 : mov 0x1c(%esp),%edx 0x4ef952cb : mov 0x20(%esp),%esi 0x4ef952cf : mov 0x24(%esp),%edi 0x4ef952d3 : mov $0xc0,%eax 0x4ef952d8 : call *%gs:0x10 0x4ef952df : pop %edi 0x4ef952e0 : pop %esi 0x4ef952e1 : pop %ebx 0x4ef952e2 : pop %ebp 0x4ef952e3 : cmp $0xfffff000,%eax 0x4ef952e8 : ja 0x4ef952f6 0x4ef952ea : ret 0x4ef952eb : pop %edi 0x4ef952ec : pop %esi 0x4ef952ed : pop %ebx 0x4ef952ee : pop %ebp 0x4ef952ef : mov $0xffffffea,%eax 0x4ef952f4 : jmp 0x4ef952f6 0x4ef952f6 : call 0x4efd8b33 0x4ef952fb : add $0xd3d05,%ecx 0x4ef95301 : mov -0x10c(%ecx),%ecx 0x4ef95307 : neg %eax 0x4ef95309 : mov %eax,%gs:(%ecx) 0x4ef9530c : or $0xffffffff,%eax 0x4ef9530f : ret
             0x4ef952e3 <+67>:    cmp    $0xfffff000,%eax
             0x4ef952e8 <+72>:    ja     0x4ef952f6 <mmap64+86>
          
             0x4ef952f6 <+86>:    call   0x4efd8b33 <__x86.get_pc_thunk.cx>
             0x4ef952fb <+91>:    add    $0xd3d05,%ecx
             0x4ef95301 <+97>:    mov    -0x10c(%ecx),%ecx
             0x4ef95307 <+103>:   neg    %eax
             0x4ef95309 <+105>:   mov    %eax,%gs:(%ecx)
             0x4ef9530c <+108>:   or     $0xffffffff,%eax
             0x4ef9530f <+111>:   ret