Gcc 气体组件代码exit()';s与SIGSEGV

Gcc 气体组件代码exit()';s与SIGSEGV,gcc,assembly,ld,gnu-assembler,low-level,Gcc,Assembly,Ld,Gnu Assembler,Low Level,我正在玩GAS assembly并链接它,而不使用gcc。相反,我使用作为汇编程序,并链接到ld 我的代码: .section .text .globl _start _start: xorq %rax, %rax movb $60, %al movb $1, %dil int $0x80 我用于组装和链接的命令: as -g -D -o test.o test.S && ld --format elf64-x86-64 -o test te

我正在玩GAS assembly并链接它,而不使用gcc。相反,我使用作为汇编程序,并链接到ld

我的代码:

.section .text
.globl _start
_start:
    xorq %rax, %rax
    movb $60, %al
    movb $1, %dil
    int $0x80
我用于组装和链接的命令:

 as -g -D -o test.o test.S && ld  --format elf64-x86-64 -o test test.o
这是调试之前/之后的gdb

(gdb) disas _start
Dump of assembler code for function _start:
   0x0000000000400078 <+0>:     xor    %rax,%rax
   0x000000000040007b <+3>:     mov    $0x3c,%al
   0x000000000040007d <+5>:     mov    $0x1,%dil
   0x0000000000400080 <+8>:     int    $0x80
End of assembler dump.
(gdb) b *_start+8
Breakpoint 1 at 0x400080: file test.S, line 7.
(gdb) r
Starting program: /tmp/test

Breakpoint 1, _start () at test.S:7
7           int $0x80
(gdb) i r
rax            0x3c     60
rbx            0x0      0
rcx            0x0      0
rdx            0x0      0
rsi            0x0      0
rdi            0x1      1
rbp            0x0      0x0
rsp            0x7fffffffebc0   0x7fffffffebc0
r8             0x0      0
r9             0x0      0
r10            0x0      0
r11            0x0      0
r12            0x0      0
r13            0x0      0
r14            0x0      0
r15            0x0      0
rip            0x400080 0x400080 <_start+8>
eflags         0x246    [ PF ZF IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400082 in ?? ()
(gdb) i r
rax            0x12     18
rbx            0x0      0
rcx            0x0      0
rdx            0x0      0
rsi            0x0      0
rdi            0x1      1
rbp            0x0      0x0
rsp            0x7fffffffebc0   0x7fffffffebc0
r8             0x0      0
r9             0x0      0
r10            0x0      0
r11            0x0      0
r12            0x0      0
r13            0x0      0
r14            0x0      0
r15            0x0      0
rip            0x400082 0x400082
eflags         0x10246  [ PF ZF IF RF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
(gdb) x/x $rip
0x400082:       0x00000000
(gdb) x/x $rip-2
0x400080 <_start+8>:    0x000080cd

您确实应该将
syscall
而不是
int$0x80
与64位代码一起使用。问题在于
int$0x80
system call使用32位Linux系统调用号。Sysexit是1而不是60。通过
int$0x80
进行的32位系统调用可在以下位置找到:。像这样的32位系统调用(即使在64位代码中)也遵循通过ebx、ecx、edx、esi、edi、ebp(按顺序)传递参数的32位约定。但我重申,对于64位代码,请使用
syscall
指令,而不是
int$0x80
使用syscall修复了问题。尽管如此,unistd_64.h中的exit syscall显示为$60:
/usr/include/asm/unistd_64.h:64:#define u NR_exit 60
是,因为
int$0x80
是32位系统调用接口,而不是64位系统调用接口。unistd_64.h系统调用应用于
syscall
指令,而不是
int$0x80
。我在第一条评论的链接中给出了32位系统调用(及其系统调用号)的链接。与64位
syscall
寄存器相比,具有
int$0x80
的参数也通过不同的寄存器
syscall
int$0x80
具有完全不同的约定和编号。吹毛求疵:
as
不是编译器。这是一个汇编程序。因此,你不能用它编译东西,只能组装它们。对不起,你是对的。我知道as的用途,但我用错了它的名字。谢谢你真的应该使用
syscall
而不是
int$0x80
和64位代码。问题在于
int$0x80
system call使用32位Linux系统调用号。Sysexit是1而不是60。通过
int$0x80
进行的32位系统调用可在以下位置找到:。像这样的32位系统调用(即使在64位代码中)也遵循通过ebx、ecx、edx、esi、edi、ebp(按顺序)传递参数的32位约定。但我重申,对于64位代码,请使用
syscall
指令,而不是
int$0x80
使用syscall修复了问题。尽管如此,unistd_64.h中的exit syscall显示为$60:
/usr/include/asm/unistd_64.h:64:#define u NR_exit 60
是,因为
int$0x80
是32位系统调用接口,而不是64位系统调用接口。unistd_64.h系统调用应用于
syscall
指令,而不是
int$0x80
。我在第一条评论的链接中给出了32位系统调用(及其系统调用号)的链接。与64位
syscall
寄存器相比,具有
int$0x80
的参数也通过不同的寄存器
syscall
int$0x80
具有完全不同的约定和编号。吹毛求疵:
as
不是编译器。这是一个汇编程序。因此,你不能用它编译东西,只能组装它们。对不起,你是对的。我知道as的用途,但我用错了它的名字。谢谢
$ strace ./test
execve("./test", ["./test"], [/* 18 vars */]) = 0
exit(1)                                 = 18
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x12} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault (core dumped)