『Binary Hacks』(高林哲, 鵜飼文敏, 佐藤祐介, 浜地慎一郎, 首藤一幸)での覚え書き(とかつっこみとか), この本は手を動かしてみないと面白さ半減やね.
>% gcc hello.c && wc -c ./a.out > 12893 ./a.out >% gcc -s hello.c && wc -c ./a.out > 2748 ./a.out
int func()
{ // この括弧と
try {
} catch (...) {
}
} // この括弧が省略できる
long pagesize = (int)sysconf(_SC_PAGESIZE);
class Udiv : public Xbyak::CodeGenerator {
// 最適化された割り算コードの動的生成
void generate(unsigned int dividend)
{
...
mov(edx, int(m));
mul(edx);
if (a) {
add(eax, int(m));
adc(edx, 0);
}
if (len) {
shr(edx, len);
}
mov(eax, edx);
ret();
}
...
Udiv udiv;
udiv.generate(d);
int (*div)(unsigned int) = (int (*)(unsigned int))udiv.getCode();
for (int i = 0; i < 10000; i++) {
int a = i / d;
int b = div(i);
assert(a == b);
}
main()
{
int a = 3;
*(short*)&a = 4;
}
>gcc -O2 -Wstrict-aliasing=2 t.c
>warning: dereferencing type-punned pointer will break \
>strict-aliasing rules
extern "C" {
void __cyg_profile_func_enter(void *funcAddr, void *callSite)
__attribute__((no_instrument_function));
void __cyg_profile_func_exit(void *funcAddr, void *callSite)
__attribute__((no_instrument_function));
}
void __cyg_profile_func_enter(void *funcAddr, void *callSite)
{
printf("enter=%p, from %p\n", funcAddr, callSite);
}
void __cyg_profile_func_exit(void *funcAddr, void *callSite)
{
printf("leave=%p, from %p\n", funcAddr, callSite);
}
>g++ -O2 -c bfdsymbol.cpp
>g++ -finstrument-functions dump_symbols.cpp -o bfd -lbfd bfdsymbol.o
>cat dump_symbols.cpp
#include <stdio.h>
#include <stdlib.h>
#include "bfdsymbol.h"
extern "C" void func1()
{
}
void func2()
{
func1();
printf("this function is %s\n", GetSymbolString((void*)func2));
}
void func3()
{
func2();
}
void func4()
{
func2();
func3();
}
int main(int argc, char *argv[])
{
func3();
func4();
func2();
return 0;
}
>./bfd
in main [0x8048e38]
in func3 [0x8048d70]
in func2 [0x8048cf2]
in func1 [0x8048cc4]
this function is func2
in func4 [0x8048dd2]
in func2 [0x8048cf2]
in func1 [0x8048cc4]
(snip)
; for FPU
%define IM 0x01
%define DM 0x02
%define ZM 0x04
%define OM 0x08
%define UM 0x10
%define PM 0x20
; for SSE2/SSE3
%define EIM (1<<7)
%define EDM (1<<8)
%define EZM (1<<9)
%define EOM (1<<10)
%define EUM (1<<11)
%define EPM (1<<12)
segment_text
proc func
; FPUの例外マスク設定
; get cw
push eax
fstcw word [esp]
pop eax
and eax, ~(IM | DM | ZM |OM |UM | PM)
; set cw
push eax
fldcw word [esp] ; (1)
pop eax
; calc
fldz
fldz
fdivp st1 ; (2)
faddp st0 ; (3)
; SSE2の例外マスク設定
; get mxcsr
push eax
stmxcsr [esp]
and dword [esp], ~(EIM | EDM | EZM | EOM | EUM | EPM)
ldmxcsr [esp] ; (4)
pop eax
pxor xm0, xm0
divps xm0, xm0 ; (5)
ret