为什么这个ASM代码演示会在x86/64Linux机器中引发分段故障



现在代码在这里:

.code32
#PURPOSE - Given a number, this program computes the
# factorial. For example, the factorial of
# 3 is 3 * 2 * 1, or 6. The factorial of
# 4 is 4 * 3 * 2 * 1, or 24, and so on.
#
.section .data
#This program has no global data
.section .text
.globl _start
.globl factorial #this is unneeded unless we want to share
_start:
pushl $4 
call factorial
addl $4, %esp
#the stack
movl %eax, %ebx 
#status
movl $1, %eax
int $0x80
.type factorial,@function
factorial:
pushl %ebp
movl %esp, %ebp 
movl 8(%ebp), %eax
cmpl $1, %eax 
je end_factorial
decl %eax 
pushl %eax 
call factorial 
movl 8(%ebp), %ebx 
imull %ebx, %eax
end_factorial:
movl %ebp, %esp
popl %ebp 
ret 

此代码位于从头开始编程我需要帮助才能在WSL2中正确运行此代码。好吧,作为标题,为什么这个ASM代码演示会在x86/64Linux机器中引发分段故障?我是ASM代码的新手。感谢中国。

在程序集代码中,当调用factorial时,使用带有pushl $4的堆栈传递参数。这是32位程序集,需要链接为32位可执行文件。在64位中,参数在寄存器中传递,在这种情况下是%rdi(第一个参数(。

64位x86 cpu可以运行32位代码,但二进制需要对此进行标记。使用gcc -m32 test.s -nostdlib -o test编译代码,然后使用gdb:进行调试

gdb ./test.1
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
...
Reading symbols from ./test.1...
(No debugging symbols found in ./test.1)
(gdb) b _start
Breakpoint 1 at 0x1000
(gdb) r
Starting program: /tmp/test.1 
Breakpoint 1, 0x56556000 in _start ()
(gdb) set disassemble-next-line on
(gdb) si
0x56556014 in factorial ()
=> 0x56556014 <factorial+1>:    89 e5   mov    %esp,%ebp
(gdb) 
0x56556016 in factorial ()
=> 0x56556016 <factorial+3>:    8b 45 08        mov    0x8(%ebp),%eax
(gdb) 
0x56556019 in factorial ()
=> 0x56556019 <factorial+6>:    83 f8 01        cmp    $0x1,%eax
(gdb) 
0x5655601c in factorial ()
=> 0x5655601c <factorial+9>:    74 0d   je     0x5655602b <end_factorial>
(gdb) 

最新更新