[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Pgubook-readers] Problems assembling and linking
From: |
Guillaume Yziquel |
Subject: |
Re: [Pgubook-readers] Problems assembling and linking |
Date: |
Sun, 3 Jul 2011 05:00:48 +0200 |
User-agent: |
Mutt/1.5.20 (2009-06-14) |
Hi.
Le Saturday 02 Jul 2011 à 22:28:03 (-0400), Kenny Hegeland a écrit :
> I'm just getting into the book and I've hit a snag when attempting to
> assemble and link the power function example, originally I was getting
> "Error: illegal suffix", I can't get access to the full error currently.
>
> I'm using x86-64, with some googling I was able to find popq, and pushq with
> registers having a prefix of r instead of e. When changing code to use q
> suffixes instead of l suffixes I can get the code to assemble and link, but
> it seems to loop continuously, eventually giving a segmentation fault.
>
> I tried assembling and linking with
>
> as --32 power.s -o power.o
> ld -melf_i386 power.o -o power
>
> And the code exactly as the book has it and it assembled and linked fine, but
> again, infinite loop to eventual segmentation fault. I'd rather not have to
> assemble and link for 32 bit and I would like to learn the correct
> instructions for x86-64. Any help on where I can find equivalents of the
> instruction set the book uses?
>
> I'm very new to assembly so bear with me if ive left out some important
> information, I do have 7-8 months java experience so I'm not entirely a
> beginner, but far from advanced at programming.
It's been a while since I haven't worried to much about assembly, so
the following code may have rotten, but you should perhaps give it a
try. I put it up together when I was trying to adapt the book's code to
x86-64. I think the main issue is that calling conventions are different
for x86-64 and i386. Info for x86-64:
http://www.vikaskumar.org/amd64/index.htm
http://www.intel.com/Assets/PDF/manual/253667.pdf
[glibc sources]: sysdeps/unix/sysv/linux/x86_64/syscall.S
Info about syscalls in unistd.h
Also check out http://www.x86-64.org/
Code:
#PURPOSE: Program to illustrate how functions work
# This program will compute the value of
# 2^3 + 5^2
#
#Note that amd64 linux has a very different calling convention
#than i386. See the ABI documentation on x86-64.org. See also
#http://www.sun.com/bigadmin/features/articles/amd64_debugging.jsp
#Everything in the main program is stored in registers,
#so the data section doesn't have anything.
.section .data
.section .text
.globl _start
_start:
movq $3, %rsi #setting second argument in %rsi
movq $2, %rdi #setting first argument in %rdi
call power #call the function
pushq %rax #save the first answer before
#calling the next function
movq $2, %rsi #setting second argument in %rsi
movq $5, %rdi #setting first argument in %rdi
call power #call the function
popq %rbx #The second answer is already
#in %rax. We saved the
#first answer onto the stack,
#so now we can just pop it
#out into %rbx
addq %rax, %rbx #add them together
#the result is in %rbx
movq %rbx, %rdi #putting the result in the
#%rdi register for exit()
movq $0x3c, %rax #setting the code for exit()
syscall
#PURPOSE: This function is used to compute
# the value of a number raised to
# a power.
#
#INPUT: First argument - the base number
# Second argument - the power to raise it to
#
#OUTPUT: Will give the result as a return value
#
#NOTES: The power must be 1 or greater
#
#VARIABLES:
# %rbx - holds the base number
# %rcx - holds the power
#
# -4(%rbp) - holds the current result
#
# %rax is used for temporary storage
#
.type power, @function
power:
pushq %rbp #save old base pointer
movq %rsp, %rbp #make stack pointer the base pointer
subq $8, %rsp #get room for our local storage
movq %rdi, %rbx #put first argument in %rbx
movq %rsi, %rcx #put second argument in %rcx
movq %rbx, -8(%rbp) #store current result
power_loop_start:
cmpq $1, %rcx #if the power is 1, we are done
je end_power
movq -8(%rbp), %rax #move the current result in %rax
imulq %rbx, %rax #multiply the current result by
#the base number
movq %rax, -8(%rbp) #store the current result
decq %rcx #decrease the power
jmp power_loop_start #run for the next power
end_power:
movq -8(%rbp), %rax #return value goes into %rax
leaveq #restore the stack pointer
#and the base pointer
retq
--
Guillaume Yziquel