実際にSPFをエンドミルでフライスを最高速で廻して切削してみました。そこそ
こいけるかも。下面はやはりムシれてしまうけれど、端面はいいし、角が崩れ
ないのもいい。これは成功。
金属の切削の場合、切削時に発生する熱のかなりの量(ちょっと忘れた)は切子 がもっていってくれるのだけど、木の場合はそれがない。木工ルーター程、高 回転でもないし、杞憂だとは思う。

愛用のPORTEGE3440CTがこの有様で、悩んでいる。去年は結局このまま使いきっ てしまった。なんとか使えないことはないんだけど...

金属の切削の場合、切削時に発生する熱のかなりの量(ちょっと忘れた)は切子 がもっていってくれるのだけど、木の場合はそれがない。木工ルーター程、高 回転でもないし、杞憂だとは思う。

愛用のPORTEGE3440CTがこの有様で、悩んでいる。去年は結局このまま使いきっ てしまった。なんとか使えないことはないんだけど...

i386-gccの呼出規約について。
Caller saved: eax, ecx, edx
Callee saved: ebx, esi, edi, ebp, esp
Return value: eax
Frame pointer ebp
Stack pointer esp
引数は全てスタックに右から積む。引数のスタックの巻戻しはcallerがやる。
__attribute__((regparm (NUM)))や、コンパイルオプションの-mregparm=NUMで
最大3つまで(順番はeax, edx, ecx)レジスタ渡しとすることができる。
残りは右からスタックに積む。
fastcallの場合はecx, edxの順で最初の二つをレジスタ渡し。これはi386のみ。
`fastcall'
On the Intel 386, the `fastcall' attribute causes the compiler to
pass the first argument (if of integral type) in the register ECX
and the second argument (if of integral type) in the register EDX.
Subsequent and other typed arguments are passed on the stack.
The called function will pop the arguments off the stack. If the
number of arguments is variable all arguments are pushed on the
stack.
`regparm (NUMBER)'
On the Intel 386, the `regparm' attribute causes the compiler to
pass arguments number one to NUMBER if they are of integral type
in registers EAX, EDX, and ECX instead of on the stack. Functions
that take a variable number of arguments will continue to be
passed all of their arguments on the stack.
Beware that on some ELF systems this attribute is unsuitable for
global functions in shared libraries with lazy binding (which is
the default). Lazy binding will send the first call via resolving
code in the loader, which might assume EAX, EDX and ECX can be
clobbered, as per the standard calling conventions. Solaris 8 is
affected by this. GNU systems with GLIBC 2.1 or higher, and
FreeBSD, are believed to be safe since the loaders there save all
registers. (Lazy binding can be disabled with the linker or the
loader if desired, to avoid the problem.)
`-mregparm=NUM'
Control how many registers are used to pass integer arguments. By
default, no registers are used to pass arguments, and at most 3
registers can be used. You can control this behavior for a
specific function by using the function attribute `regparm'.
*Note Function Attributes::.
*Warning:* if you use this switch, and NUM is nonzero, then you
must build all modules with the same value, including any
libraries. This includes the system libraries and startup modules.
int
a (int a0, int a1, int a2, int a3)
{
return a0 + a1 + a2 - a3;
}
int
b ()
{
return a (0, 1, 2, 3);
}
main ()
{
a (0xaa55, 4, 3, 2);
}
cc -O2 -fomit-frame-pointer -finhibit-size-directive -fno-ident -S a.c
.file "a.c"
.text
.p2align 2,,3
.globl a
.type a, @function
a:
movl 8(%esp), %eax
addl 4(%esp), %eax
addl 12(%esp), %eax
subl 16(%esp), %eax
ret
.p2align 2,,3
.globl b
.type b, @function
b:
pushl $3 右から詰む。(cdecl)
pushl $2
pushl $1
pushl $0
call a
addl $16, %esp 引数領域の巻戻しはcallerがやる。
ret
.p2align 2,,3
.globl main
.type main, @function
main:
leal 4(%esp), %ecx; lea フラグレジスタを書きかえない。
andl $-16, %esp
pushl -4(%ecx)
pushl %ecx
popl %ecx
leal -4(%ecx), %esp
ret
cdecl 右側の引数から積む。callarがスタックを戻す。
Pascal 左側から。calleeがスタックを戻す。
レジスタ渡しについて。
int
a (int a0, int a1, int a2, int a3)
{
return a0 + a1 + a2 - a3;
}
int
b ()
{
return a (0, 1, 2, 3);
}
main ()
{
a (0xaa55, 4, 3, 2);
}
gcc -O2 -fomit-frame-pointer -finhibit-size-directive -fno-ident -mregparm=3 -S a.c
.file "a.c"
.text
.p2align 2,,3
.globl a
.type a, @function
a:
addl %edx, %eax
addl %ecx, %eax
subl 4(%esp), %eax
ret
.p2align 2,,3
.globl b
.type b, @function
b:
pushl $3 ;(引数4)
movl $2, %ecx ;(引数3)
movl $1, %edx ;(引数2)
xorl %eax, %eax ;(引数1)
call a
popl %edx ;callerがスタックを戻す。2つまでならpoplを重ねる。
ret
.p2align 2,,3
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ecx
popl %ecx
leal -4(%ecx), %esp
ret
3引数までeax, edx, ecxで渡される。ボーランド__fastcall
attributeを使う場合は定義にもattributeをつける。
int a (int, int, int, int, int) __attribute__((regparm (3)));
int __attribute__((regparm (3)))
a (int a0, int a1, int a2, int a3, int a4)
{
return a0 + a1 + a2 - a3 + a4;
}
int
b ()
{
return a (0, 1, 2, 3, 4);
}
pushl $4 レジスタに乗せきれない分は右から。
pushl $3
movl $2, %ecx
movl $1, %edx
xorl %eax, %eax
call a
