GNU Assembler (gas) on x86_64

Marc Lijour marc-bbkyySd1vPWsTnJN9+BGXg at public.gmane.org
Wed Dec 20 06:59:11 UTC 2006


Thank you for this big bag of explanations and tricks!

As it sounds I am a total newbie in assembly language. I appreciate your 
pointers.

Your code worked perfectly right out of the box. 

Marc

On Wednesday 20 December 2006 00:46, D. Hugh Redelmeier wrote:
> | From: Marc Lijour <marc-bbkyySd1vPWsTnJN9+BGXg at public.gmane.org>
> |
> | I try to follow Richard Blum "Assembly Language" book (Wrox) which
> | focuses on Linux and GNU gas -which is a very good thing.
> |
> | However, my platform is x86_64, not i686. I could tweak the code a little
> | bit to avoid segfault by using information gathered at
>
> Why code for x86_64 if you don't have the manual?  At least some
> x86_64 linux distros (eg. Fedora) let you compile and run i386 code.
>
> | http://www.x86-64.org/documentation/assembly . Now the code looks like
> | this:
> |
> | # Using printf from libc
> | .section .data
> | output:
> |         .asciz "The processor Vendor ID is '%s'\n"
> |
> | .section .bss
> |         .lcomm  buffer, 12
> | .section .text
> | .globl _start
> | _start:
> |         nop
> |         movq    $0, %rax
> |         cpuid
> |         movq    $buffer, %rdi
> |         movq    %rbx, (%rdi)
> |         movq    %rdx, 4 (%rdi)
> |         movq    %rcx, 8 (%rdi)
> |         pushq   $buffer
> |         pushq   $output
> |         call    printf
> |         addq    $8, %rsp
> |         pushq   $0
> |         call    exit
> |
> | The unmodified example from the book gives this result on Intel i686:
> | $ ./cpuid2_i686
> | The processor Vendor ID is 'GenuineIntel'
> |
> | But the code above gives me this on my AMD64:
> | $ ./cpuid2_x86_64
> | AuthenticAMD
> |
> | (followed by no newline)
> |
> | Question: why is the string (label output) not used by printf??
>
> I expect that you need to pay attention to the ABI (Application Binary
> Interface).  This spells out coding conventions for subroutine calls,
> among other things.
>
> Google got me to http://www.x86-64.org/documentation/abi.pdf
>
> Section 3.2 talks about the function calling sequence.
>
> Section 3.2.3 talks about parameter passing.
>
> The first pointer arg should be passed in %rdi.  The second should be
> passed in %rsi.
>
> Don't forget to terminate C strings with '\0'.
>
> You can also find a manuals for the x86_64.  I used this one:
>  
> http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/245
>94.pdf I discovered (on page 365) that CPUID operates on 32-bit operands
> even when the CPU is in 64-bit mode.  Page 102 explains CPUID without
> making this explicit.
>
> Here's my guess at what your code should look like (UNTESTED).
> Warning: I've never written a line of x86_64 code in my life.  The
> last Intel processor that I did much assembly for was the i8080.
>
> .section .data
> output:
>         .asciz "The processor Vendor ID is '%s'\n"
>
> .section .bss
> # polite to align the buffer since it is accessed as 4-byte units.
> 	.align 4
> # note: length needs to be 13 (room for '\0')
>         .lcomm  buffer, 13
> .section .text
> .globl _start
> _start:
> # CPUID argument is only 32 bits.
>         movl    $0, %eax
>         cpuid
>         movq    $buffer, %rsi
> # CPUID results are only 32-bit units
>         movl    %ebx, (%rsi)
>         movl    %edx, 4 (%rsi)
>         movl    %ecx, 8 (%rsi)
> # terminate the string
> 	movb $0, 12(%rsi)
> # printf second arg in %rdi
>         movq   $output, %rdi
>         call    printf
>
> # exit(0)
> 	movq	$0, %rdi
>         call    exit
>
> Useful trick: write something in C and see what gcc comes up with (-S
> flag causes it to compile to assembly code).
>
> Problem: it seems to write bad assembler that gas apparently corrects.
> I see movl used for 64-bit moves, for example.  A mystery that I won't
> try to unravel.
>
> Here's my sample C code:
>     #include <stdio.h>
>
>     int
>     main()
>     {
> 	printf("format %s\n", "arg");
> 	return 0;
>     }
> --
> The Toronto Linux Users Group.      Meetings: http://gtalug.org/
> TLUG requests: Linux topics, No HTML, wrap text below 80 columns
> How to UNSUBSCRIBE: http://gtalug.org/wiki/Mailing_lists
--
The Toronto Linux Users Group.      Meetings: http://gtalug.org/
TLUG requests: Linux topics, No HTML, wrap text below 80 columns
How to UNSUBSCRIBE: http://gtalug.org/wiki/Mailing_lists





More information about the Legacy mailing list