I'm reading the book: "Professional assembly language".
I want to use dynamic linking.
I'm using AT&T syntax with GNU assembler.
My computer has Ubuntu 12.04 (in a 64 bit system).
I'm trying to display the vendor ID string using the cpuid assembler opcode and
printf C function instead of linux system calls.
Code of hello.s
.code32
.section .data
output:
.asciz "The processor Vendor ID is '%s'\n"
.section .bss
.lcomm buffer, 12
.section .text
.globl _start
_start:
movl $0, %eax
cpuid
movl $buffer, %edi
movl %ebx, (%edi)
movl %edx, 4(%edi)
movl %ecx, 8(%edi)
pushl $buffer
pushl $output
call printf
addl $8, %esp
pushl $0
call exit
I executed the next commands:
> $ as -o hello.o hello.s
> $ ld -dynamic-linker /lib/ld-linux.so.2 -o hello -lc hello.o
> $ ./hello
bash: ./hello: Accessing a corrupted shared library
But I'm getting the error message shown above, something about a corrupted shared library (that's the error that I want to solve)
I don't care too much about the code (because I understand it)
I just want to learn how to use dynamic linking using assembly code and GAS.
So if you have any assembly code
that uses dynamic linking I appreciate if you can show me the "as" and "ld" commands that you use.
PS: In case somebody wants to understand what does the code:
The CPUID instruction uses a single register value as input .
The EAX register is used to determine what
information is produced by the CPUID instruction.
Depending on the value of the EAX register, the CPUID
instruction will produce different information about the processor in the EBX, ECX, and EDX registers.
The information is returned as a series of bit values and flags, which must be interpreted to their proper meaning
This code utilizes the zero option (movl $0, %eax) to retrieve the simple Vendor ID
string from the processor. When the value of zero is placed in the EAX register, and the CPUID instruction
is executed, the processor returns the Vendor ID string in the EBX, EDX , and ECX registers as follows:
❑ EBX contains the low 4 bytes of the string.
❑ EDX contains the middle 4 bytes of the string.
❑ ECX contains the last 4 bytes of the string.
The string values are placed in the registers in little-endian format;
This code uses the standard C library functions: printf and exit instead of linux system calls.
-m elf_i386
to the ld command line. Your.code32
may cover it, but you might want to try-32
to the (G)as command line, too. As you seem to understand, the trick is to convince your 64-bit tools that you want 32-bit code. Or you could write 64-bit code (not what's in your book). Or you could go back to system calls (easiest, IMO). – Frank Kotlermain
so that it has a chance to initialize. You should also compile and link usinggcc -m32 -o hello hello.s
, which is simple and does everything for you. You can pass-v
option to see what exactly it is doing, but be prepared for a shock :) – Jester