User:David-Bryant

From Qt Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Triangles oblique.png

Hi. My name is David Bryant. I'm a retired actuary / assembly language (IBM 360 / 370) programmer living in Canyon Lake, Texas. I have been contributing to the KDE project for about three years, mostly doing documentation for the PIM subsystem (KMail, KAddressBook, etc.) I've been struggling to wrap my head around "object-oriented" programs for years. I joined the Qt wiki because I want to understand the c++ code in various KDE programs better than I do now.

Oops is hard!

The other day I encountered a problem while trying to run an example program presented in this article. I think the instructions are a bit unclear. Anyway, I managed to create a compiler error in Qt-Creator that I couldn't circumvent ... the linkage editor was looking for an external symbol "_start" that the c++ compiler had not generated (because I didn't have a "main()" function defined in the source code).

After digging around the internet a little bit, I ran across this snippet of code (compiled with gcc).

#include<stdio.h>
#include<stdlib.h>
void _start()
{
    int x = my_fun(); //calling custom main function
    exit(x);
}
  
int my_fun() // our custom main function
{
    printf("Hello world!/n");
    return 0;
}

If this code is compiled / linked with "gcc -nostartfiles -o example example.c". I get a warning message from the C compiler, but it does create an object program, which looks like this:

example:      file format elf64-x86-64
Disassembly of section .plt:

0000000000001000 <puts@plt-0x10>:
    1000:	ff 35 02 30 00 00    	push   0x3002(%rip)         # 4008 <_GLOBAL_OFFSET_TABLE_+0x8>
    1006:	ff 25 04 30 00 00    	jmp    *0x3004(%rip)        # 4010 <_GLOBAL_OFFSET_TABLE_+0x10>
    100c:	0f 1f 40 00          	nopl   0x0(%rax)

0000000000001010 <puts@plt>:
    1010:	ff 25 02 30 00 00    	jmp    *0x3002(%rip)        # 4018 <puts@GLIBC_2.2.5>
    1016:	68 00 00 00 00       	push   $0x0
    101b:	e9 e0 ff ff ff       	jmp    1000 <puts@plt-0x10>

0000000000001020 <exit@plt>:
    1020:	ff 25 fa 2f 00 00    	jmp    *0x2ffa(%rip)        # 4020 <exit@GLIBC_2.2.5>
    1026:	68 01 00 00 00       	push   $0x1
    102b:	e9 d0 ff ff ff       	jmp    1000 <puts@plt-0x10>

Disassembly of section .text:

0000000000001030 <_start>:
    1030:	55                   	push   %rbp
    1031:	48 89 e5             	mov    %rsp,%rbp
    1034:	48 83 ec 10          	sub    $0x10,%rsp
    1038:	b8 00 00 00 00       	mov    $0x0,%eax
    103d:	e8 0d 00 00 00       	call   104f <my_fun>
    1042:	89 45 fc             	mov    %eax,-0x4(%rbp)
    1045:	8b 45 fc             	mov    -0x4(%rbp),%eax
    1048:	89 c7                	mov    %eax,%edi
    104a:	e8 d1 ff ff ff       	call   1020 <exit@plt>

000000000000104f <my_fun>:
    104f:	55                   	push   %rbp
    1050:	48 89 e5             	mov    %rsp,%rbp
    1053:	48 8d 05 a6 0f 00 00 	lea    0xfa6(%rip),%rax        # 2000 <my_fun+0xfb1>
    105a:	48 89 c7             	mov    %rax,%rdi
    105d:	e8 ae ff ff ff       	call   1010 <puts@plt>
    1062:	b8 00 00 00 00       	mov    $0x0,%eax
    1067:	5d                   	pop    %rbp
    1068:	c3                   	ret

Believe it or not, this actually makes more sense (to me) than the C source code. I can see parameter lists being created, registers being saved and restored, subroutines being called, etc. The only thing I don't see is the literal "Hello World!\n", which is presumably in the object module's data section. I had to dig a little deeper, but I found that, too.

Disassembly of section .rodata:
0000000000002000 <.rodata>:
    2000:	48                   	rex.W
    2001:	65 6c                	gs insb (%dx),%es:(%rdi)
    2003:	6c                   	insb   (%dx),%es:(%rdi)
    2004:	6f                   	outsl  %ds:(%rsi),(%dx)
    2005:	20 77 6f             	and    %dh,0x6f(%rdi)
    2008:	72 6c                	jb     2076 <__GNU_EH_FRAME_HDR+0x66>
    200a:	64 21 00             	and    %eax,%fs:(%rax)

I think this is pretty funny. The "objdump" program is interpreting a bunch of ASCII data as machine instructions! It would make more sense if it displayed like a regular hexdump:

Disassembly of section .rodata:
0000000000002000 <.rodata>:
0002000 6548 6c6c 206f 6f77 6c72 2164 0000 0000    eH ll .o ow lr !d .. ..