I am compiling the following assembly program on debian wheezy, but it will not run giving me the error:
-bash: ./power: cannot execute binary file
.section data
.section text
.global _start
_start:
# do first calc and save the answer
pushl $3
pushl $2
call power
addl $8, %esp
pushl %eax
# do second calc
pushl $2
pushl $5
call power
addl $8, %esp
# add both together
popl %ebx
addl %eax, %ebx
# exit with answer as return status
movl $1, %eax
int $0x80
.type power, @function
power:
# ?
pushl %ebp
movl %esp, %ebp
subl $4, %esp
# load params
movl 8(%ebp), %ebx
movl 12(%ebp), %ecx
movl %ebx, -4(%ebp)
power_loop_start:
# have we looped down to 1?
cmpl $1, %ecx
je end_power
# multiply prev result by base and store
movl -4(%ebp), %eax
imull %ebx, %eax
movl %eax, -4(%ebp)
# go again
decl %ecx
jmp power_loop_start
end_power:
movl -4(%ebp), %eax
movl %ebp, %esp
popl %ebp
ret
I run with:
as power.s -o power.o
ld power.o -o power
./power
Both uname -m
and arch
give me i686, and the binary outputs this on objdump -x
:
$ objdump -x power
power: file format elf32-i386
power
architecture: i386, flags 0x00000012:
EXEC_P, HAS_SYMS
start address 0x00000000
Sections:
Idx Name Size VMA LMA File off Algn
0 text 0000004a 00000000 00000000 00000034 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l d text 00000000 text
00000023 l F text 00000000 power
00000032 l text 00000000 power_loop_start
00000043 l text 00000000 end_power
00000000 g text 00000000 _start
08049034 g *ABS* 00000000 __bss_start
08049034 g *ABS* 00000000 _edata
08049034 g *ABS* 00000000 _end
Not sure what I am doing wrong.
This example is from the book "Programming from the ground up". I have tried on a Red Hat x86_64 machine, with as
flags --32
and ld
flags -m elf_i386
, it all compiles fine just like on the x86 machine, but when executing gives the same error.
You have a typo: .section text
should be .section .text
(note the dot) or just .text
While the issue is caused by a typo I feel it is worthy of some explanation especially since you so nicely provided all the details :)
While you can name your sections however you like (and this is why the tools didn't complain), each section has some flags. In this case you see in the objdump output: CONTENTS, READONLY
. What this means is that this section is not executable, in fact it's not even loaded. (Arguably the error message could be a little more precise.)
Okay, so why isn't it executable? The assembler recognizes some common section names and sets up the flags properly. For a custom name, you have to do that manually, for example by doing .section text, "ax"
which sets ALLOC
and CODE
. See also the .section
directive in the manual and this answer about the various flags.
User contributions licensed under CC BY-SA 3.0