2012年8月9日 星期四

作業系統之前的程式 (2) - c++ global object ctor/dtor can not be invoked

作業系統之前的程式 (1) - c++ 篇的差別是只把 Io io 搬到 WinMain 的外面, 但結果可是大大不同。

cppb.cpp
 1 __asm__(".code16gcc\n");
 2 #include "io.h"
 3 
 4 /*
 5  * c bootloader
 6  */
 7 
 8 //#define POINTER_TEST
 9 
10 
11 int bbb=0; // test bss section
12 void *__dso_handle;
13 int __cxa_atexit(void (*destructor) (void *), void *arg, void *__dso_handle)
14 {
15   return 0;
16 }
17 
18   Io io;
19 
20 extern "C" void WinMain(void)
21 {
22   __asm__ ("mov  %cs, %ax\n");
23   __asm__ ("mov  %ax, %ds\n");
24   __asm__ ("mov  %ax, %ss\n");
25   __asm__ ("mov  $0xfff0, %sp\n");
26   {
27   io.print("hello cpp class\r\n");
28   }
29   #if 0
30   unsigned char *vb = (unsigned char *)0xb8000;
31   *vb = 'A';
32   *(unsigned char *)0xb8001 = 0xc;
33   *(unsigned char *)0xb8002 = 'B';
34   *(unsigned char *)0xb8003 = 0x9;
35   *(unsigned char *)0xb8004 = '@';
36   *(unsigned char *)0xb8005 = 0xc;
37   #endif
38   while(1);
39 }


ld -m elf_i386 -static -Tcpp.ld -nostdlib -M -o cppb.elf cppb.o io.o > cb.elf.map
ld: section .sig loaded at [0000000000007dfe,0000000000007dff] overlaps section .rodata loaded at [0000000000007df4,0000000000007e21]
cppb.o: In function `__static_initialization_and_destruction_0':
/home/descent/test/simple_os.test/c-bootloader/cpp/cppb.cpp:18: undefined reference to `__cxa_atexit'
make: *** [cppb.elf] Error 1

12 void *__dso_handle;
13 int __cxa_atexit(void (*destructor) (void *), void *arg, void *__dso_handle)
14 {
15   return 0;
16 }
18   Io io;

為了使用 global object 要補上 __cxa_atexit (註冊 dtor 用), __dso_handle (dynamic share object 相關), 這樣 link, compile 才會過。而令人害怕的是:

__static_initialization_and_destruction_0

我的 c++ 程式碼根本沒有這行 (要不是忘記 extern "C", 我可能沒發現, 不過用 objdump 還是可以看到), 所以肯定是 g++ 幹的好事。只不過把 io 宣告成 global object, 就發生了這麼大的差異。c++ 編譯器果然幹了不少事情, 也讓這支程式大於 512 byte, 看吧! c++ 的程式絕對不是大假的。

還有這個 _GLOBAL__I_io 也是 g++ 產生的。

_GLOBAL__I_io, __static_initialization_and_destruction_0 是幹嘛用的? 請參考: c++ runtime - global object ctor (0)

objdump -d cppb.elf
  1 
  2 cppb.elf:     file format elf32-i386
  3 
  4 
  5 Disassembly of section .text:
  6 
  7 00000100 <WinMain>:
  8  100: 66 55                 push   %bp
  9  102: 66 89 e5              mov    %sp,%bp
 10  105: 66 83 ec 18           sub    $0x18,%sp
 11  109: 87 db                 xchg   %ebx,%ebx
 12  10b: 8c c8                 mov    %cs,%eax
 13  10d: 8e d8                 mov    %eax,%ds
 14  10f: 8e d0                 mov    %eax,%ss
 15  111: 67 66 c7 44 24 04 f8  addr16 movw $0xf804,0x24(%si)
 16  118: 02 00                 add    (%eax),%al
 17  11a: 00 67 66              add    %ah,0x66(%edi)
 18  11d: c7 04 24 2c 03 00 00  movl   $0x32c,(%esp)
 19  124: 66 e8 8a 01           callw  2b2 <_ZN2IoD1Ev+0x26>
 20  128: 00 00                 add    %al,(%eax)
 21  12a: b8 00 4c cd 21        mov    $0x21cd4c00,%eax
 22  12f: 66 c9                 leavew 
 23  131: 66 c3                 retw   
 24 
 25 00000133 <__cxa_atexit>:
 26  133: 66 55                 push   %bp
 27  135: 66 89 e5              mov    %sp,%bp
 28  138: 66 b8 00 00           mov    $0x0,%ax
 29  13c: 00 00                 add    %al,(%eax)
 30  13e: 66 5d                 pop    %bp
 31  140: 66 c3                 retw   
 32 
 33 00000142 <_Z41__static_initialization_and_destruction_0ii>:
 34  142: 66 55                 push   %bp
 35  144: 66 89 e5              mov    %sp,%bp
 36  147: 66 83 ec 18           sub    $0x18,%sp
 37  14b: 67 66 83 7d 08 01     addr16 cmpw $0x1,0x8(%di)
 38  151: 75 3f                 jne    192 <_Z41__static_initialization_and_destruction_0ii+0x50>
 39  153: 67 66 81 7d 0c ff ff  addr16 cmpw $0xffff,0xc(%di)
 40  15a: 00 00                 add    %al,(%eax)
 41  15c: 75 34                 jne    192 <_Z41__static_initialization_and_destruction_0ii+0x50>
 42  15e: 67 66 c7 04 24 2c     addr16 movw $0x2c24,(%si)
 43  164: 03 00                 add    (%eax),%eax
 44  166: 00 66 e8              add    %ah,-0x18(%esi)
 45  169: a3 00 00 00 66        mov    %eax,0x66000000
 46  16e: b8 8c 02 00 00        mov    $0x28c,%eax
 47  173: 67 66 c7 44 24 08 30  addr16 movw $0x3008,0x24(%si)
 48  17a: 03 00                 add    (%eax),%eax
 49  17c: 00 67 66              add    %ah,0x66(%edi)
 50  17f: c7 44 24 04 2c 03 00  movl   $0x32c,0x4(%esp)
 51  186: 00 
 52  187: 67 66 89 04           addr16 mov %ax,(%si)
 53  18b: 24 66                 and    $0x66,%al
 54  18d: e8 a1 ff ff ff        call   133 <__cxa_atexit>
 55  192: 66 c9                 leavew 
 56  194: 66 c3                 retw   
 57 
 58 00000196 <_GLOBAL__I_io>:
 59  196: 66 55                 push   %bp
 60  198: 66 89 e5              mov    %sp,%bp
 61  19b: 66 83 ec 18           sub    $0x18,%sp
 62  19f: 67 66 c7 44 24 04 ff  addr16 movw $0xff04,0x24(%si)
 63  1a6: ff 00                 incl   (%eax)
 64  1a8: 00 67 66              add    %ah,0x66(%edi)
 65  1ab: c7 04 24 01 00 00 00  movl   $0x1,(%esp)
 66  1b2: 66 e8 8a ff           callw  140 <__cxa_atexit+0xd>
 67  1b6: ff                    (bad)  
 68  1b7: ff 66 c9              jmp    *-0x37(%esi)
 69  1ba: 66 c3                 retw   
 70 
 71 000001bc <_ZN2IoC2Ev>:
 72  1bc: 66 55                 push   %bp
 73  1be: 66 89 e5              mov    %sp,%bp
 74  1c1: 66 83 ec 18           sub    $0x18,%sp
 75  1c5: 67 66 8b 45 08        addr16 mov 0x8(%di),%ax
 76  1ca: 67 66 c7 00 0a 03     addr16 movw $0x30a,(%bx,%si)
 77  1d0: 00 00                 add    %al,(%eax)
 78  1d2: 67 66 c7 44 24 04 18  addr16 movw $0x1804,0x24(%si)
 79  1d9: 03 00                 add    (%eax),%eax
 80  1db: 00 67 66              add    %ah,0x66(%edi)
 81  1de: 8b 45 08              mov    0x8(%ebp),%eax
 82  1e1: 67 66 89 04           addr16 mov %ax,(%si)
 83  1e5: 24 66                 and    $0x66,%al
 84  1e7: e8 c8 00 00 00        call   2b4 <_ZN2Io5printEPKc>
 85  1ec: 67 66 8b 45 08        addr16 mov 0x8(%di),%ax
 86  1f1: 67 66 8b 00           addr16 mov (%bx,%si),%ax
 87  1f5: 67 66 89 44 24        addr16 mov %ax,0x24(%si)
 88  1fa: 04 67                 add    $0x67,%al
 89  1fc: 66 8b 45 08           mov    0x8(%ebp),%ax
 90  200: 67 66 89 04           addr16 mov %ax,(%si)
 91  204: 24 66                 and    $0x66,%al
 92  206: e8 a9 00 00 00        call   2b4 <_ZN2Io5printEPKc>
 93  20b: 66 c9                 leavew 
 94  20d: 66 c3                 retw   
 95  20f: 90                    nop
 96 
 97 00000210 <_ZN2IoC1Ev>:
 98  210: 66 55                 push   %bp
 99  212: 66 89 e5              mov    %sp,%bp
100  215: 66 83 ec 18           sub    $0x18,%sp
101  219: 67 66 8b 45 08        addr16 mov 0x8(%di),%ax
102  21e: 67 66 c7 00 0a 03     addr16 movw $0x30a,(%bx,%si)
103  224: 00 00                 add    %al,(%eax)
104  226: 67 66 c7 44 24 04 18  addr16 movw $0x1804,0x24(%si)
105  22d: 03 00                 add    (%eax),%eax
106  22f: 00 67 66              add    %ah,0x66(%edi)
107  232: 8b 45 08              mov    0x8(%ebp),%eax
108  235: 67 66 89 04           addr16 mov %ax,(%si)
109  239: 24 66                 and    $0x66,%al
110  23b: e8 74 00 00 00        call   2b4 <_ZN2Io5printEPKc>
111  240: 67 66 8b 45 08        addr16 mov 0x8(%di),%ax
112  245: 67 66 8b 00           addr16 mov (%bx,%si),%ax
113  249: 67 66 89 44 24        addr16 mov %ax,0x24(%si)
114  24e: 04 67                 add    $0x67,%al
115  250: 66 8b 45 08           mov    0x8(%ebp),%ax
116  254: 67 66 89 04           addr16 mov %ax,(%si)
117  258: 24 66                 and    $0x66,%al
118  25a: e8 55 00 00 00        call   2b4 <_ZN2Io5printEPKc>
119  25f: 66 c9                 leavew 
120  261: 66 c3                 retw   
121  263: 90                    nop
122 
123 00000264 <_ZN2IoD2Ev>:
124  264: 66 55                 push   %bp
125  266: 66 89 e5              mov    %sp,%bp
126  269: 66 83 ec 18           sub    $0x18,%sp
127  26d: 67 66 c7 44 24 04 1f  addr16 movw $0x1f04,0x24(%si)
128  274: 03 00                 add    (%eax),%eax
129  276: 00 67 66              add    %ah,0x66(%edi)
130  279: 8b 45 08              mov    0x8(%ebp),%eax
131  27c: 67 66 89 04           addr16 mov %ax,(%si)
132  280: 24 66                 and    $0x66,%al
133  282: e8 2d 00 00 00        call   2b4 <_ZN2Io5printEPKc>
134  287: 66 c9                 leavew 
135  289: 66 c3                 retw   
136  28b: 90                    nop
137 
138 0000028c <_ZN2IoD1Ev>:
139  28c: 66 55                 push   %bp
140  28e: 66 89 e5              mov    %sp,%bp
141  291: 66 83 ec 18           sub    $0x18,%sp
142  295: 67 66 c7 44 24 04 1f  addr16 movw $0x1f04,0x24(%si)
143  29c: 03 00                 add    (%eax),%eax
144  29e: 00 67 66              add    %ah,0x66(%edi)
145  2a1: 8b 45 08              mov    0x8(%ebp),%eax
146  2a4: 67 66 89 04           addr16 mov %ax,(%si)
147  2a8: 24 66                 and    $0x66,%al
148  2aa: e8 05 00 00 00        call   2b4 <_ZN2Io5printEPKc>
149  2af: 66 c9                 leavew 
150  2b1: 66 c3                 retw   
151  2b3: 90                    nop
152 
153 000002b4 <_ZN2Io5printEPKc>:
154  2b4: 66 55                 push   %bp
155  2b6: 66 89 e5              mov    %sp,%bp
156  2b9: 66 53                 push   %bx
157  2bb: eb 22                 jmp    2df <_ZN2Io5printEPKc+0x2b>
158  2bd: 67 66 8b 45 0c        addr16 mov 0xc(%di),%ax
159  2c2: 67 66 0f b6 00        addr16 movzbw (%bx,%si),%ax
160  2c7: 66 0f be c0           movsbw %al,%ax
161  2cb: 80 cc 0e              or     $0xe,%ah
162  2ce: 66 ba 07 00           mov    $0x7,%dx
163  2d2: 00 00                 add    %al,(%eax)
164  2d4: 66 89 d3              mov    %dx,%bx
165  2d7: cd 10                 int    $0x10
166  2d9: 67 66 83 45 0c 01     addr16 addw $0x1,0xc(%di)
167  2df: 67 66 8b 45 0c        addr16 mov 0xc(%di),%ax
168  2e4: 67 66 0f b6 00        addr16 movzbw (%bx,%si),%ax
169  2e9: 84 c0                 test   %al,%al
170  2eb: 0f 95 c0              setne  %al
171  2ee: 84 c0                 test   %al,%al
172  2f0: 75 cb                 jne    2bd <_ZN2Io5printEPKc+0x9>
173  2f2: 66 5b                 pop    %bx
174  2f4: 66 5d                 pop    %bp
175  2f6: 66 c3                 retw   

objdump -m i8086 -d cppb.elf
  1 
  2 cppb.elf:     file format elf32-i386
  3 
  4 
  5 Disassembly of section .text:
  6 
  7 00000100 <WinMain>:
  8  100: 66 55                 push   %ebp
  9  102: 66 89 e5              mov    %esp,%ebp
 10  105: 66 83 ec 18           sub    $0x18,%esp
 11  109: 87 db                 xchg   %bx,%bx
 12  10b: 8c c8                 mov    %cs,%ax
 13  10d: 8e d8                 mov    %ax,%ds
 14  10f: 8e d0                 mov    %ax,%ss
 15  111: 67 66 c7 44 24 04 f8  addr32 movl $0x2f8,0x4(%esp)
 16  118: 02 00 00 
 17  11b: 67 66 c7 04 24 2c 03  addr32 movl $0x32c,(%esp)
 18  122: 00 00 
 19  124: 66 e8 8a 01 00 00     calll  2b4 <_ZN2Io5printEPKc>
 20  12a: b8 00 4c              mov    $0x4c00,%ax
 21  12d: cd 21                 int    $0x21
 22  12f: 66 c9                 leavel 
 23  131: 66 c3                 retl   
 24 
 25 00000133 <__cxa_atexit>:
 26  133: 66 55                 push   %ebp
 27  135: 66 89 e5              mov    %esp,%ebp
 28  138: 66 b8 00 00 00 00     mov    $0x0,%eax
 29  13e: 66 5d                 pop    %ebp
 30  140: 66 c3                 retl   
 31 
 32 00000142 <_Z41__static_initialization_and_destruction_0ii>:
 33  142: 66 55                 push   %ebp
 34  144: 66 89 e5              mov    %esp,%ebp
 35  147: 66 83 ec 18           sub    $0x18,%esp
 36  14b: 67 66 83 7d 08 01     addr32 cmpl $0x1,0x8(%ebp)
 37  151: 75 3f                 jne    192 <_Z41__static_initialization_and_destruction_0ii+0x50>
 38  153: 67 66 81 7d 0c ff ff  addr32 cmpl $0xffff,0xc(%ebp)
 39  15a: 00 00 
 40  15c: 75 34                 jne    192 <_Z41__static_initialization_and_destruction_0ii+0x50>
 41  15e: 67 66 c7 04 24 2c 03  addr32 movl $0x32c,(%esp)
 42  165: 00 00 
 43  167: 66 e8 a3 00 00 00     calll  210 <_ZN2IoC1Ev>
 44  16d: 66 b8 8c 02 00 00     mov    $0x28c,%eax
 45  173: 67 66 c7 44 24 08 30  addr32 movl $0x330,0x8(%esp)
 46  17a: 03 00 00 
 47  17d: 67 66 c7 44 24 04 2c  addr32 movl $0x32c,0x4(%esp)
 48  184: 03 00 00 
 49  187: 67 66 89 04 24        addr32 mov %eax,(%esp)
 50  18c: 66 e8 a1 ff ff ff     calll  133 <__cxa_atexit>
 51  192: 66 c9                 leavel 
 52  194: 66 c3                 retl   
 53 
 54 00000196 <_GLOBAL__I_io>:
 55  196: 66 55                 push   %ebp
 56  198: 66 89 e5              mov    %esp,%ebp
 57  19b: 66 83 ec 18           sub    $0x18,%esp
 58  19f: 67 66 c7 44 24 04 ff  addr32 movl $0xffff,0x4(%esp)
 59  1a6: ff 00 00 
 60  1a9: 67 66 c7 04 24 01 00  addr32 movl $0x1,(%esp)
 61  1b0: 00 00 
 62  1b2: 66 e8 8a ff ff ff     calll  142 <_Z41__static_initialization_and_destruction_0ii>
 63  1b8: 66 c9                 leavel 
 64  1ba: 66 c3                 retl   
 65 
 66 000001bc <_ZN2IoC2Ev>:
 67  1bc: 66 55                 push   %ebp
 68  1be: 66 89 e5              mov    %esp,%ebp
 69  1c1: 66 83 ec 18           sub    $0x18,%esp
 70  1c5: 67 66 8b 45 08        addr32 mov 0x8(%ebp),%eax
 71  1ca: 67 66 c7 00 0a 03 00  addr32 movl $0x30a,(%eax)
 72  1d1: 00 
 73  1d2: 67 66 c7 44 24 04 18  addr32 movl $0x318,0x4(%esp)
 74  1d9: 03 00 00 
 75  1dc: 67 66 8b 45 08        addr32 mov 0x8(%ebp),%eax
 76  1e1: 67 66 89 04 24        addr32 mov %eax,(%esp)
 77  1e6: 66 e8 c8 00 00 00     calll  2b4 <_ZN2Io5printEPKc>
 78  1ec: 67 66 8b 45 08        addr32 mov 0x8(%ebp),%eax
 79  1f1: 67 66 8b 00           addr32 mov (%eax),%eax
 80  1f5: 67 66 89 44 24 04     addr32 mov %eax,0x4(%esp)
 81  1fb: 67 66 8b 45 08        addr32 mov 0x8(%ebp),%eax
 82  200: 67 66 89 04 24        addr32 mov %eax,(%esp)
 83  205: 66 e8 a9 00 00 00     calll  2b4 <_ZN2Io5printEPKc>
 84  20b: 66 c9                 leavel 
 85  20d: 66 c3                 retl   
 86  20f: 90                    nop
 87 
 88 00000210 <_ZN2IoC1Ev>:
 89  210: 66 55                 push   %ebp
 90  212: 66 89 e5              mov    %esp,%ebp
 91  215: 66 83 ec 18           sub    $0x18,%esp
 92  219: 67 66 8b 45 08        addr32 mov 0x8(%ebp),%eax
 93  21e: 67 66 c7 00 0a 03 00  addr32 movl $0x30a,(%eax)
 94  225: 00 
 95  226: 67 66 c7 44 24 04 18  addr32 movl $0x318,0x4(%esp)
 96  22d: 03 00 00 
 97  230: 67 66 8b 45 08        addr32 mov 0x8(%ebp),%eax
 98  235: 67 66 89 04 24        addr32 mov %eax,(%esp)
 99  23a: 66 e8 74 00 00 00     calll  2b4 <_ZN2Io5printEPKc>
100  240: 67 66 8b 45 08        addr32 mov 0x8(%ebp),%eax
101  245: 67 66 8b 00           addr32 mov (%eax),%eax
102  249: 67 66 89 44 24 04     addr32 mov %eax,0x4(%esp)
103  24f: 67 66 8b 45 08        addr32 mov 0x8(%ebp),%eax
104  254: 67 66 89 04 24        addr32 mov %eax,(%esp)
105  259: 66 e8 55 00 00 00     calll  2b4 <_ZN2Io5printEPKc>
106  25f: 66 c9                 leavel 
107  261: 66 c3                 retl   
108  263: 90                    nop
109 
110 00000264 <_ZN2IoD2Ev>:
111  264: 66 55                 push   %ebp
112  266: 66 89 e5              mov    %esp,%ebp
113  269: 66 83 ec 18           sub    $0x18,%esp
114  26d: 67 66 c7 44 24 04 1f  addr32 movl $0x31f,0x4(%esp)
115  274: 03 00 00 
116  277: 67 66 8b 45 08        addr32 mov 0x8(%ebp),%eax
117  27c: 67 66 89 04 24        addr32 mov %eax,(%esp)
118  281: 66 e8 2d 00 00 00     calll  2b4 <_ZN2Io5printEPKc>
119  287: 66 c9                 leavel 
120  289: 66 c3                 retl   
121  28b: 90                    nop
122 
123 0000028c <_ZN2IoD1Ev>:
124  28c: 66 55                 push   %ebp
125  28e: 66 89 e5              mov    %esp,%ebp
126  291: 66 83 ec 18           sub    $0x18,%esp
127  295: 67 66 c7 44 24 04 1f  addr32 movl $0x31f,0x4(%esp)
128  29c: 03 00 00 
129  29f: 67 66 8b 45 08        addr32 mov 0x8(%ebp),%eax
130  2a4: 67 66 89 04 24        addr32 mov %eax,(%esp)
131  2a9: 66 e8 05 00 00 00     calll  2b4 <_ZN2Io5printEPKc>
132  2af: 66 c9                 leavel 
133  2b1: 66 c3                 retl   
134  2b3: 90                    nop
135 
136 000002b4 <_ZN2Io5printEPKc>:
137  2b4: 66 55                 push   %ebp
138  2b6: 66 89 e5              mov    %esp,%ebp
139  2b9: 66 53                 push   %ebx
140  2bb: eb 22                 jmp    2df <_ZN2Io5printEPKc+0x2b>
141  2bd: 67 66 8b 45 0c        addr32 mov 0xc(%ebp),%eax
142  2c2: 67 66 0f b6 00        addr32 movzbl (%eax),%eax
143  2c7: 66 0f be c0           movsbl %al,%eax
144  2cb: 80 cc 0e              or     $0xe,%ah
145  2ce: 66 ba 07 00 00 00     mov    $0x7,%edx
146  2d4: 66 89 d3              mov    %edx,%ebx
147  2d7: cd 10                 int    $0x10
148  2d9: 67 66 83 45 0c 01     addr32 addl $0x1,0xc(%ebp)
149  2df: 67 66 8b 45 0c        addr32 mov 0xc(%ebp),%eax
150  2e4: 67 66 0f b6 00        addr32 movzbl (%eax),%eax
151  2e9: 84 c0                 test   %al,%al
152  2eb: 0f 95 c0              setne  %al
153  2ee: 84 c0                 test   %al,%al
154  2f0: 75 cb                 jne    2bd <_ZN2Io5printEPKc+0x9>
155  2f2: 66 5b                 pop    %ebx
156  2f4: 66 5d                 pop    %ebp
157  2f6: 66 c3                 retl   

objdump 為我們帶來一些資訊:

 33 00000142 <_Z41__static_initialization_and_destruction_0ii>:
 58 00000196 <_GLOBAL__I_io>:

原來是讓 _GLOBAL__I_io> call 的 (這是 16bit code, 所以使用 -m i8086 會得到比較正確的反組譯結果)。

這是額外產生的程式碼, 當然還有不知道為什麼有兩份的 ctor/dtor。其他的不用看, 那是我拿來佔版面用的。

global_object$ c++filt _Z41__static_initialization_and_destruction_0ii
__static_initialization_and_destruction_0(int, int)

c++filt 可以 demangle 還原本來的 symbol。

_GLOBAL__I_io 用猜的都能感覺出來是 global io 的 ctor, 不過要怎麼證明呢?等我證明之後會有下一篇 (沒有下一篇的話就是我錯了或是還沒證明出來 XD)。

還真的搞錯了, 和我想的不太一樣。ref: c++ runtime - global object ctor (0)

cppb.cpp
 1 __asm__(".code16gcc\n");
 2 #include "io.h"
 3 
 4 /*
 5  * c bootloader
 6  */
 7 
 8 //#define POINTER_TEST
 9 
10 
11 #define BOCHS_MB __asm__ __volatile__("xchg %bx, %bx");
12 
13 
14   Io io;
15 
16 extern "C" void WinMain(void)
17 {
18   BOCHS_MB  
19   #if 1
20   __asm__ ("mov  %cs, %ax\n");
21   __asm__ ("mov  %ax, %ds\n");
22   __asm__ ("mov  %ax, %ss\n");
23   //__asm__ ("mov  $0xfff0, %sp\n");
24   {
25   io.print("hello cpp class\r\n");
26   }
27   #if 0
28   unsigned char *vb = (unsigned char *)0xb8000;
29   *vb = 'A';
30   *(unsigned char *)0xb8001 = 0xc;
31   *(unsigned char *)0xb8002 = 'B';
32   *(unsigned char *)0xb8003 = 0x9;
33   *(unsigned char *)0xb8004 = '@';
34   *(unsigned char *)0xb8005 = 0xc;
35   #endif
36   //while(1);
37   __asm__ ("mov     $0x4c00, %ax\n");
38   __asm__ ("int     $0x21\n"); //   回到 DOS
39 
40   #endif
41 }
42 
43 
44 
45 void *__dso_handle;
46 extern "C"
47 {
48 int __cxa_atexit(void (*destructor) (void *), void *arg, void *__dso_handle)
49 {
50   return 0;
51 }
52 }

-rwxr-xr-x 1 descent descent     556 2012-08-08 13:31 cppb.bin
-rwxr-xr-x 1 descent descent    4979 2012-08-08 13:31 cppb.elf

由於超過 512, 所以我改到 msdos 下執行。

From write_os
顛覆 c++ 程式員的想像, ctor/dtor 完全沒執行 (請對照作業系統之前的程式 (1) - c++ 篇執行畫面)。

從這篇開始, 標題要改成 c++ runtime, 畢竟這是 os 下的程式, 無法再稱為作業系統之前的程式。

這是 g++ 4.4.3 的結果, g++ (Debian 4.7.0-9) 4.7.0 又不一樣了。不要整我啦!
自己對, 我不解說了。

g++ 4.7objdump -m i8086 -d cppb.elf
  1 
  2 cppb.elf:     file format elf32-i386
  3 
  4 
  5 Disassembly of section .text:
  6 
  7 00000100 <WinMain>:
  8  100: 66 55                 push   %ebp
  9  102: 66 89 e5              mov    %esp,%ebp
 10  105: 66 83 ec 28           sub    $0x28,%esp
 11  109: 87 db                 xchg   %bx,%bx
 12  10b: 8c c8                 mov    %cs,%ax
 13  10d: 8e d8                 mov    %ax,%ds
 14  10f: 8e d0                 mov    %ax,%ss
 15  111: 66 a1 e4 02           mov    0x2e4,%eax
 16  115: 67 66 89 45 f4        mov    %eax,-0xc(%ebp)
 17  11a: 66 a1 e4 02           mov    0x2e4,%eax
 18  11e: 67 66 89 45 f0        mov    %eax,-0x10(%ebp)
 19  123: 67 66 8b 45 f4        mov    -0xc(%ebp),%eax
 20  128: 67 66 89 45 ec        mov    %eax,-0x14(%ebp)
 21  12d: 67 66 8b 45 ec        mov    -0x14(%ebp),%eax
 22  132: 66 ff d0              calll  *%eax
 23  135: 67 66 c7 44 24 04 00  movl   $0x1000,0x4(%eax,%eax,1)
 24  13c: 10 00 00 
 25  13f: 67 66 c7 04 24 4c 10  movl   $0x104c,(%eax,%eax,1)
 26  146: 00 00 
 27  148: 66 e8 52 01 00 00     calll  2a0 <_ZN2Io5printEPKc>
 28  14e: b8 00 4c              mov    $0x4c00,%ax
 29  151: cd 21                 int    $0x21
 30  153: 66 c9                 leavel 
 31  155: 66 c3                 retl   
 32 
 33 00000157 <__cxa_atexit>:
 34  157: 66 55                 push   %ebp
 35  159: 66 89 e5              mov    %esp,%ebp
 36  15c: 66 83 ec 18           sub    $0x18,%esp
 37  160: 67 66 c7 44 24 04 12  movl   $0x1012,0x4(%eax,%eax,1)
 38  167: 10 00 00 
 39  16a: 67 66 c7 04 24 4c 10  movl   $0x104c,(%eax,%eax,1)
 40  171: 00 00 
 41  173: 66 e8 27 01 00 00     calll  2a0 <_ZN2Io5printEPKc>
 42  179: 66 b8 00 00 00 00     mov    $0x0,%eax
 43  17f: 66 c9                 leavel 
 44  181: 66 c3                 retl   
 45 
 46 00000183 <__cxa_finalize>:
 47  183: 66 55                 push   %ebp
 48  185: 66 89 e5              mov    %esp,%ebp
 49  188: 66 83 ec 18           sub    $0x18,%esp
 50  18c: 67 66 c7 44 24 04 1d  movl   $0x101d,0x4(%eax,%eax,1)
 51  193: 10 00 00 
 52  196: 67 66 c7 04 24 4c 10  movl   $0x104c,(%eax,%eax,1)
 53  19d: 00 00 
 54  19f: 66 e8 fb 00 00 00     calll  2a0 <_ZN2Io5printEPKc>
 55  1a5: 66 c9                 leavel 
 56  1a7: 66 c3                 retl   
 57 
 58 000001a9 <_Z41__static_initialization_and_destruction_0ii>:
 59  1a9: 66 55                 push   %ebp
 60  1ab: 66 89 e5              mov    %esp,%ebp
 61  1ae: 66 83 ec 18           sub    $0x18,%esp
 62  1b2: 67 66 83 7d 08 01     cmpl   $0x1,0x8(%ebp)
 63  1b8: 75 3d                 jne    1f7 <_Z41__static_initialization_and_destruction_0ii+0x4e>
 64  1ba: 67 66 81 7d 0c ff ff  cmpl   $0xffff,0xc(%ebp)
 65  1c1: 00 00 
 66  1c3: 75 32                 jne    1f7 <_Z41__static_initialization_and_destruction_0ii+0x4e>
 67  1c5: 67 66 c7 04 24 4c 10  movl   $0x104c,(%eax,%eax,1)
 68  1cc: 00 00 
 69  1ce: 66 e8 50 00 00 00     calll  224 <_ZN2IoC1Ev>
 70  1d4: 67 66 c7 44 24 08 50  movl   $0x1050,0x8(%eax,%eax,1)
 71  1db: 10 00 00 
 72  1de: 67 66 c7 44 24 04 4c  movl   $0x104c,0x4(%eax,%eax,1)
 73  1e5: 10 00 00 
 74  1e8: 67 66 c7 04 24 78 02  movl   $0x278,(%eax,%eax,1)
 75  1ef: 00 00 
 76  1f1: 66 e8 60 ff ff ff     calll  157 <__cxa_atexit>
 77  1f7: 66 c9                 leavel 
 78  1f9: 66 c3                 retl   
 79 
 80 000001fb <_GLOBAL__sub_I_io>:
 81  1fb: 66 55                 push   %ebp
 82  1fd: 66 89 e5              mov    %esp,%ebp
 83  200: 66 83 ec 18           sub    $0x18,%esp
 84  204: 67 66 c7 44 24 04 ff  movl   $0xffff,0x4(%eax,%eax,1)
 85  20b: ff 00 00 
 86  20e: 67 66 c7 04 24 01 00  movl   $0x1,(%eax,%eax,1)
 87  215: 00 00 
 88  217: 66 e8 8c ff ff ff     calll  1a9 <_Z41__static_initialization_and_destruction_0ii>
 89  21d: 66 c9                 leavel 
 90  21f: 66 c3                 retl   
 91  221: 00 00                 add    %al,(%bx,%si)
 92  ...
 93 
 94 00000224 <_ZN2IoC1Ev>:
 95  224: 66 55                 push   %ebp
 96  226: 66 89 e5              mov    %esp,%ebp
 97  229: 66 83 ec 18           sub    $0x18,%esp
 98  22d: 67 66 8b 45 08        mov    0x8(%ebp),%eax
 99  232: 67 66 c7 00 2a 10 00  movl   $0x102a,(%eax)
100  239: 00 
101  23a: 67 66 c7 44 24 04 38  movl   $0x1038,0x4(%eax,%eax,1)
102  241: 10 00 00 
103  244: 67 66 8b 45 08        mov    0x8(%ebp),%eax
104  249: 67 66 89 04 24        mov    %eax,(%eax,%eax,1)
105  24e: 66 e8 4c 00 00 00     calll  2a0 <_ZN2Io5printEPKc>
106  254: 67 66 8b 45 08        mov    0x8(%ebp),%eax
107  259: 67 66 8b 00           mov    (%eax),%eax
108  25d: 67 66 89 44 24 04     mov    %eax,0x4(%eax,%eax,1)
109  263: 67 66 8b 45 08        mov    0x8(%ebp),%eax
110  268: 67 66 89 04 24        mov    %eax,(%eax,%eax,1)
111  26d: 66 e8 2d 00 00 00     calll  2a0 <_ZN2Io5printEPKc>
112  273: 66 c9                 leavel 
113  275: 66 c3                 retl   
114  277: 90                    nop
115 
116 00000278 <_ZN2IoD1Ev>:
117  278: 66 55                 push   %ebp
118  27a: 66 89 e5              mov    %esp,%ebp
119  27d: 66 83 ec 18           sub    $0x18,%esp
120  281: 67 66 c7 44 24 04 3f  movl   $0x103f,0x4(%eax,%eax,1)
121  288: 10 00 00 
122  28b: 67 66 8b 45 08        mov    0x8(%ebp),%eax
123  290: 67 66 89 04 24        mov    %eax,(%eax,%eax,1)
124  295: 66 e8 05 00 00 00     calll  2a0 <_ZN2Io5printEPKc>
125  29b: 66 c9                 leavel 
126  29d: 66 c3                 retl   
127  29f: 90                    nop
128 
129 000002a0 <_ZN2Io5printEPKc>:
130  2a0: 66 55                 push   %ebp
131  2a2: 66 89 e5              mov    %esp,%ebp
132  2a5: 66 53                 push   %ebx
133  2a7: eb 22                 jmp    2cb <_ZN2Io5printEPKc+0x2b>
134  2a9: 67 66 8b 45 0c        mov    0xc(%ebp),%eax
135  2ae: 67 66 0f b6 00        movzbl (%eax),%eax
136  2b3: 66 0f be c0           movsbl %al,%eax
137  2b7: 80 cc 0e              or     $0xe,%ah
138  2ba: 66 ba 07 00 00 00     mov    $0x7,%edx
139  2c0: 66 89 d3              mov    %edx,%ebx
140  2c3: cd 10                 int    $0x10
141  2c5: 67 66 83 45 0c 01     addl   $0x1,0xc(%ebp)
142  2cb: 67 66 8b 45 0c        mov    0xc(%ebp),%eax
143  2d0: 67 66 0f b6 00        movzbl (%eax),%eax
144  2d5: 84 c0                 test   %al,%al
145  2d7: 0f 95 c0              setne  %al
146  2da: 84 c0                 test   %al,%al
147  2dc: 75 cb                 jne    2a9 <_ZN2Io5printEPKc+0x9>
148  2de: 66 5b                 pop    %ebx
149  2e0: 66 5d                 pop    %ebp
150  2e2: 66 c3                 retl   

ref:

沒有留言:

張貼留言

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。