Entire code is:
# Purpose: a program that shows how functions work
# This program will calculate
# 2 ^ 3 + 5 ^ 2
# All contents of the main program are stored in registers,
# Therefore, the data segment does not contain any content
.code32
.section .data
.section .text
.globl _start
_start:
pushl $3 # Press in the second parameter
pushl $2 # Press in the first parameter
call power # Call function
addl $8,%esp # Move the stack pointer backward
pushl %eax # Saves the return value from the first call before calling the next function
pushl $2 # Press in the second parameter
pushl $5 # Press in the first parameter
call power # call function
addl $8,%esp # Moves the stack pointer backward
popl %ebx # The return value from the second call is already in %eax,
# Now pop the return value from the first call into %ebx
addl %eax,%ebx # Add the two, and the result is in %ebx
movl $1,%eax # quit
int $0x80
# Purpose: This function is used to calculate the power of a number
#
# Input: first parameter - base number
# Second parameter - the exponent of the base
#
# Output: The result is given as a return value
#
# variables:
# % ebx - Save base number
# % ecx - Save index
#
# -4(%ebp) - Save the current result
#
# %eax for temporary storage
#
.type power,@function
power:
pushl %ebp # Retain the old base address pointer
movl %esp,%ebp # Set the base pointer to the stack pointer
subl $4,%esp # Reserve space for local storage
movl 8(%ebp),%ebx # Put the first argument in %ebx
movl 12(%ebp),%ecx # Put the second argument in %ecx
movl %ebx,-4(%ebp) # Storing the current result
power_loop_start:
cmpl $1,%ecx # If it's to the first power, then we've got the result
je end_power
movl -4(%ebp),%eax # Moves the current result into %eax
imull %ebx,%eax # Multiply the current result by the base
movl %eax,-4(%ebp) # Save the current result
decl %ecx # exponential decrease
jmp power_loop_start # Power calculation for the decreasing exponent
end_power:
movl -4(%ebp),%eax # Return value moved to %eax
movl %ebp,%esp # Recovery stack pointer
popl %ebp # Restore the base address pointer
ret
I'm running in x86_64, and at compile time I get this message:
$ as power.s -o power.o
power.s: Assembler messages:
power.s:14: error: invalid instruction suffix for `push'
power.s:15: error: invalid instruction suffix for `push'
power.s:18: error: invalid instruction suffix for `push'
power.s:21: error: invalid instruction suffix for `push'
power.s:22: error: invalid instruction suffix for `push'
power.s:25: error: invalid instruction suffix for `pop'
power.s:50: error: invalid instruction suffix for `push'
power.s:72: error: invalid instruction suffix for `pop'
So I added ".code32 ", the problem was solved, and I could compile and link smoothly, but during the run, there was an error again. I used GDB to trace, and the error message was as follows:
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from power...
(No debugging symbols found in power)
(gdb) run
Starting program: /github/assembly/04/power
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401029 in power ()
(gdb) bt
#0 0x0000000000401029 in power ()
Backtrace stopped: Cannot access memory at address 0xffffdfd4
(gdb) frame 0
#0 0x0000000000401029 in power ()
(gdb) info f
Stack level 0, frame at 0xffffdfdc:
rip = 0x401029 in power; saved rip = <not saved>
Outermost frame: Cannot access memory at address 0xffffdfd4
Arglist at 0xffffdfcc, args:
Locals at 0xffffdfcc, Previous frame's sp is 0xffffdfdc
Cannot access memory at address 0xffffdfcc
(gdb) i register
rax 0x0 0
rbx 0x0 0
rcx 0x0 0
rdx 0x0 0
rsi 0x0 0
rdi 0x0 0
rbp 0xffffdfd0 0xffffdfd0
rsp 0xffffdfcc 0xffffdfcc
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 0x401029 0x401029 <power+6>
eflags 0x10296 [ PF AF SF IF RF ]
--Type <RET> for more, q to quit, c to continue without paging--
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb)
After I disassemble the code, it looks like this:
$ objdump -d power
power: file format elf64-x86-64
Disassembly of section .text:
0000000000401000 <_start>:
401000: 6a 03 pushq $0x3
401002: 6a 02 pushq $0x2
401004: e8 1a 00 00 00 callq 401023 <power>
401009: 83 c4 08 add $0x8,%esp
40100c: 50 push %rax
40100d: 6a 02 pushq $0x2
40100f: 6a 05 pushq $0x5
401011: e8 0d 00 00 00 callq 401023 <power>
401016: 83 c4 08 add $0x8,%esp
401019: 5b pop %rbx
40101a: 01 c3 add %eax,%ebx
40101c: b8 01 00 00 00 mov $0x1,%eax
401021: cd 80 int $0x80
0000000000401023 <power>:
401023: 55 push %rbp
401024: 89 e5 mov %esp,%ebp
401026: 83 ec 04 sub $0x4,%esp
401029: 8b 5d 08 mov 0x8(%rbp),%ebx
40102c: 8b 4d 0c mov 0xc(%rbp),%ecx
40102f: 89 5d fc mov %ebx,-0x4(%rbp)
0000000000401032 <power_loop_start>:
401032: 83 f9 01 cmp $0x1,%ecx
401035: 74 0c je 401043 <end_power>
401037: 8b 45 fc mov -0x4(%rbp),%eax
40103a: 0f af c3 imul %ebx,%eax
40103d: 89 45 fc mov %eax,-0x4(%rbp)
401040: 49 eb ef rex.WB jmp 401032 <power_loop_start>
0000000000401043 <end_power>:
401043: 8b 45 fc mov -0x4(%rbp),%eax
401046: 89 ec mov %ebp,%esp
401048: 5d pop %rbp
401049: c3 retq
I have checked the logic of the assembly code and found no error. If you know the answer, please let me know. Thank you very much!