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