This is a GNU-Assembly program.
.code32 #must add this line, otherwise, this program can't be complied.
.section .data
.section .text
.global _start
_start:
pushl $3 #push second argument
pushl $2 #push first argument
call power #call the function
addl $8, %esp #move the stack pointer back
pushl %eax #save the first answer before calling the next function
pushl $2 #push second argument
pushl $5 #push first argument
call power #call the function
addl $8, %esp #move the stack pointer back
#The second answer is already
#in %eax. We saved the
#first answer onto the stack,
#so now we can just pop it
#out into %ebx
popl %ebx
addl %eax, %ebx #add them together
movl $1, %eax #exit (%ebx is returned)
int $0x80
.type power, @function
#first arg-> base number
#second arg-> the power to raise
power:
pushl %ebp #save old base pointer
movl %esp, %ebp #make stack pointer the base pointer
subl $4, %esp #get room for our local storage
movl 8(%ebp), %ebx
movl 12(%ebp), %ecx
movl %ebx, -4(%ebp)
power_loop_start:
cmpl $1, %ecx
je end_power
movl -4(%ebp), %eax
imull %ebx, %eax
movl %eax, -4(%ebp)
decl %ecx
jmp power_loop_start
end_power:
movl -4(%ebp), %eax
movl %ebp, %esp
popl %ebp
ret
It can be complied when added the .code32 instruction.
$ as -g hello.s -o hello.o
$ ld hello.o -o hello
However, it always shows "segment fault" when run it.
I find that the registers of %esp and %ebp is always negative when step into power using GDB.
Breakpoint 1, _start () at hello.s:9
9 pushl $3
(gdb) n
_start () at hello.s:10
10 pushl $2
(gdb)
_start () at hello.s:11
11 call power
(gdb) s
power () at hello.s:35
35 pushl %ebp
(gdb) n
36 movl %esp, %ebp
(gdb)
37 subl $4, %esp
(gdb) n
power () at hello.s:45
45 movl 8(%ebp), %ebx
(gdb) print $ebp
$1 = -8144
(gdb) print $esp
$2 = -8148
(gdb)
How can I solve this problem. My OS is Ubuntu.
Linux locomotive-VirtualBox 5.4.0-52-generic #57~18.04.1-Ubuntu SMP Thu Oct 15 14:04:49 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux