I have the below instruction in ARM NEON code. Can you please tell me the equivalent in gcc?
label
DCFS 1.5
DCFS -1.4
I am not sure but i think the only way to do the above in gcc is using a table.
PLease let me know if there is an equivalent representation in gcc.
https://sourceware.org/binutils/docs/as/Float.html#Float
.float flonums
This directive assembles zero or more flonums, separated by commas. It has the same effect as .single.
I couldn't find any reference about alignment guarantees but from experiment it looks like there is none.
$ cat f.s
.data
.byte 0xaa
.float 3.14
.byte 0x55
.text
test:
mov r0, r1
$ as f.s -o f.o
$ objdump -s -j .data f.o
f.o: file format elf32-littlearm
Contents of section .data:
0000 aac3f548 4055 ...H#U
Related
I have been implementing just for fun a simple operating system for x86 architecture from scratch. I implemented the assembly code for the bootloader that loads the kernel from disk and enters in 32-bit mode. The kernel code that is loaded is written in C, so in order to be executed the idea is to generate the raw binary from the C code.
Firstly, I used these commands:
$gcc -ffreestanding -c kernel.c -o kernel.o -m32
$ld -o kernel.bin -Ttext 0x1000 kernel.o --oformat binary -m elf_i386
However, it didn't generate any binary giving back these errors:
kernel.o: In function 'main':
kernel.c:(.text+0xc): undefined reference to '_GLOBAL_OFFSET_TABLE_'
Just for clarity sake, the kernel.c code is:
/* kernel.c */
void main ()
{
char *video_memory = (char *) 0xb8000 ;
*video_memory = 'X';
}
Then I followed this tutorial: http://wiki.osdev.org/GCC_Cross-Compiler
to implement my own cross-compiler for my own target. It worked for my purpose, however disassembling with the command ndisasm I obtained this code:
00000000 55 push ebp
00000001 89E5 mov ebp,esp
00000003 83EC10 sub esp,byte +0x10
00000006 C745FC00800B00 mov dword [ebp-0x4],0xb8000
0000000D 8B45FC mov eax,[ebp-0x4]
00000010 C60058 mov byte [eax],0x58
00000013 90 nop
00000014 C9 leave
00000015 C3 ret
00000016 0000 add [eax],al
00000018 1400 adc al,0x0
0000001A 0000 add [eax],al
0000001C 0000 add [eax],al
0000001E 0000 add [eax],al
00000020 017A52 add [edx+0x52],edi
00000023 0001 add [ecx],al
00000025 7C08 jl 0x2f
00000027 011B add [ebx],ebx
00000029 0C04 or al,0x4
0000002B 0488 add al,0x88
0000002D 0100 add [eax],eax
0000002F 001C00 add [eax+eax],bl
00000032 0000 add [eax],al
00000034 1C00 sbb al,0x0
00000036 0000 add [eax],al
00000038 C8FFFFFF enter 0xffff,0xff
0000003C 16 push ss
0000003D 0000 add [eax],al
0000003F 0000 add [eax],al
00000041 41 inc ecx
00000042 0E push cs
00000043 088502420D05 or [ebp+0x50d4202],al
00000049 52 push edx
0000004A C50C04 lds ecx,[esp+eax]
0000004D 0400 add al,0x0
0000004F 00 db 0x00
As you can see, the first 9 rows (except for the NOP that I don't know why it is inserted) are the assembly translation of my main function. From 10 row to the end, there's a lot code that I don't know why it is here.
In the end, I have two questions:
1) Why is it produced that code?
2) Is there a way to produce the raw machine code from C without that useless stuff?
A few hints first:
avoid naming your starting routine main. It is confusing (both for the reader and perhaps for the compiler; when you don't pass -ffreestanding to gcc it is handling main very specifically). Use something else like start or begin_of_my_kernel ...
compile with gcc -v to understand what your particular compiler is doing.
you probably should ask your compiler for some optimizations and all warnings, so pass -O -Wall at least to gcc
you may want to look into the produced assembler code, so use gcc -S -O -Wall -fverbose-asm kernel.c to get the kernel.s assembler file and glance into it
as commented by Michael Petch you might want to pass -fno-exceptions
your probably need some linker script and/or some hand-written assembler for crt0
you should read something about linkers & loaders
kernel.c:(.text+0xc): undefined reference to '_GLOBAL_OFFSET_TABLE_'
This smells like something related to position-independent-code. My guess: try compiling with an explicit -fno-pic or -fno-pie
(on some Linux distributions, their gcc might be configured with some -fpic enabled by default)
PS. Don't forget to add -m32 to gcc if you want x86 32 bits binaries.
I use some third-party libraries in a project.
This project is a embedded system with a MIPS(isa32r2) core.
Recently we found a bug in the third-party library(libusb.a), but because of the time there is no technical support anymore.
so I try to disassemble the libarary.
$ mips-sde-elf-ar -x libusb.a
$ mips-sde-elf-objdump.exe -Ds -mmips:isa32r2 -EL usbhost_func.o > usbhost_func.s
in file usbhost_func.s I can get some info like:
Disassembly of section .text.usbhost_init:
00000000 :
0: 27bdffd8 addiu sp,sp,-40
4: 3c020000 lui v0,0x0
.text.usbhost_init looks like a complete disassembly functions of usbhost_init().
but there is some other info here like:
Disassembly of section .pdr:
00000000 :
0: 00000000 nop
4: 40000000 mfc0 zero,c0_index
8: fffffffc sdc3 $31,-4(ra)
... why here is ...
14: 00000008 jr zero
18: 0000001e 0x1e
1c: 0000001f 0x1f
20: 00000000 nop
Disassembly of section .gnu.attributes:
00000000 :
0: 00000f41 0xf41
4: 756e6700 jalx 5b99c00
8: 00070100 sll zero,a3,0x4
c: 03040000 0x3040000
so my question is:
What does the secton's mean like section .pdr?
Why there is some ... in setion .pdr ?
What is the srart point to disassemble a mips library?
Any hint and info are welcome.Tks.
objdump -D will try to deassemble all sections instead of sections which include valid instructions, you should use objdump -d.
.pdr is a debug information section, may not include valid instructions.
For static libraries (.a files), you should extract the object files in these libraries by ar x libfoo.a, and try to deassemble those object files you got by objdump -d.
If I define a local character array within a function and then use objdump to grab the assembly code for that particular function, can I find the memory for that array within the assembly code?
This is a question I have for a homework assignment.
Sure, as long as your array has a non-zero initializer, you should be able to find it. Here's an example I made for ARM:
char function(int i)
{
char arr[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
return arr[i];
}
Build it:
$ clang -O2 -Wall -c -o example.o example.c
Disassemble the output:
$ objdump -d example.o
example.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <function>:
0: e59f1004 ldr r1, [pc, #4] ; c <function+0xc>
4: e7d10000 ldrb r0, [r1, r0]
8: e12fff1e bx lr
c: 00000000 .word 0x00000000
Hmm - notice that .word 0x0000000 at offset 0xc? That's going to be fixed up by the linker to point to the array. Let's go check out the relocation table:
$ objdump -r example.o
example.o: file format elf32-littlearm
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000008 R_ARM_V4BX *ABS*
0000000c R_ARM_ABS32 .rodata.cst8
Aha! The word at 0xc is going to get fixed up with an absolute pointer to the .rodata.cst8 section - that sounds like what we want. Let's take a peek:
$ objdump -s -j .rodata.cst8 example.o
example.o: file format elf32-littlearm
Contents of section .rodata.cst8:
0000 01020304 05060708 ........
And there you have the contents of the array!
A local array is allocated on stack in run-time only (when the function is entered). So it doesn't present in executable.
An exception would be a static array.
I am in the process of writing a small operating system in C. I have written a bootloader and I'm now trying to get a simple C file (the "kernel") to compile with gcc:
int main(void) { return 0; }
I compile the file with the following command:
gcc kernel.c -o kernel.o -nostdlib -nostartfiles
I use the linker to create the final image using this command:
ld kernel.o -o kernel.bin -T linker.ld --oformat=binary
The contents of the linker.ld file are as follows:
SECTIONS
{
. = 0x7e00;
.text ALIGN (0x00) :
{
*(.text)
}
}
(The bootloader loads the image at address 0x7e00.)
This seems to work quite well - ld produces a 128-byte file containing the following instructions in the first 11 bytes:
00000000 55 push ebp
00000001 48 dec eax
00000002 89 E5 mov ebp, esp
00000004 B8 00 00 00 00 mov eax, 0x00000000
00000009 5D pop ebp
0000000A C3 ret
However, I can't figure out what the other 117 bytes are for. Disassembling them seems to produce a bunch of garbage that doesn't make any sense. The existence of the additional bytes has me wondering if I'm doing something wrong.
Should I be concerned?
These are additional sections, which were not stripped and not discarded. You want your linker.ld file to look like this:
SECTIONS
{
. = 0x7e00;
.text ALIGN (0x00) :
{
*(.text)
}
/DISCARD/ :
{
*(.comment)
*(.eh_frame_hdr)
*(.eh_frame)
}
}
I know what sections to discard from the output of objdump -t kernel.o.
Simple, you're using gcc, and it always put its initialization code before passing control to your main.
What's on that start up code I don't know, but they are there. As you may see there's also an comment 'GNU' on your binary, you can't print specific sectors by using objdump -s -j 'section name'.
I want to get the address of _GLOBAL_OFFSET_TABLE_ in my program. One way is to use the nm command in Linux, maybe redirect the output to a file and parse that file to get address of _GLOBAL_OFFSET_TABLE_. However, that method seems to be quite inefficient. What are some more efficient methods of doing it?
This appears to work:
// test.c
#include <stdio.h>
extern void *_GLOBAL_OFFSET_TABLE_;
int main()
{
printf("_GLOBAL_OFFSET_TABLE = %p\n", &_GLOBAL_OFFSET_TABLE_);
return 0;
}
In order to get consistent address of _GLOBAL_OFFSET_TABLE_, matching nm's result, you will need to compile your code with -fPIE to do code-gen as if linking into a position-independent executable. (Otherwise you get a small integer like 0x2ed6 with -fno-pie -no-pie). The GCC default for most modern Linux distros is -fPIE -pie, which would make nm addresses be just offsets relative to an image base, and the runtime address be ASLRed. (This is normally good for security, but you may not want it.)
$: gcc -fPIE -no-pie test.c -o test
It gives:
$ ./test
_GLOBAL_OFFSET_TABLE = 0x6006d0
However, nm thinks different:
$ nm test | fgrep GLOBAL
0000000000600868 d _GLOBAL_OFFSET_TABLE_
Or with a GCC too old to know about PIEs at all, let alone have it -fPIE -pie as the default, -fpic can work.
If you use assembly language, you can get _GLOBAL_OFFSET_TABLE_ address without get_pc_thunk.
It is tricky way. :)
Here is the sample code :
$ cat test.s
.global main
main:
lea HEREIS, %eax # Now %eax holds address of _GLOBAL_OFFSET_TABLE_
.section .got
HEREIS:
$ gcc -o test test.s
This is available because .got section is adjacent to the <.got.plt>
Therefore the symbol HEREIS and _GLOBAL_OFFSET_TABLE_ locate at same address.
PS. You can check it works with objdump.
Disassembly of section .got:
080495e8 <HEREIS-0x4>:
80495e8: 00 00 add %al,(%eax)
...
Disassembly of section .got.plt:
080495ec <_GLOBAL_OFFSET_TABLE_>:
80495ec: 00 95 04 08 00 00 add %dl,0x804(%ebp)
80495f2: 00 00 add %al,(%eax)
80495f4: 00 00 add %al,(%eax)