pgubook-readers
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]