Cで書くかアセンブラで書くか・・・
- 1 :デフォルトの名無しさん:04/09/30 02:24:11
-
下手なアセンブラコードよりも、Cで書いてコンパイラに任せた方が速い場合もあります。
こういう場合はアセンブラで、こういう場合はCで書いた方がいいよという情報をみんなで交換していきましょう。
このスレはCあるいはC++の中で使用するアセンブラに特化したスレです。アセンブラの全般の話題はこちらへ
アセンブラ… (°Д°)ハァ?
http://pc5.2ch.net/test/read.cgi/tech/1093519463/l50
- 502 :デフォルトの名無しさん:2009/10/23(金) 14:44:03
- outb %al,%dx
jmp 1f
1: jmp 1f
1:
jmp 1fのfとは一体何を表しているのでしょうか_?
- 503 :デフォルトの名無しさん:2009/10/23(金) 15:02:20
- 16進数だろjk
- 504 :デフォルトの名無しさん:2009/10/23(金) 15:02:40
- >>502
1fを含むインストラクションがあるロケーションよりも前方(表示イメージだと下)にある最初に見つかったラベルの 1:
- 505 :デフォルトの名無しさん:2009/10/23(金) 15:04:43
- ラベルの前方参照(forward reference)を示してるんじゃないかなぁ。
てか、アセンブラ何? as86じゃないよね。
- 506 :デフォルトの名無しさん:2009/10/23(金) 15:26:23
- >>503-505
なるほど、前方参照とは気づきませんでした。
- 507 :デフォルトの名無しさん:2009/10/23(金) 18:58:10
- >>505
gasだべ
- 508 :デフォルトの名無しさん:2009/10/23(金) 20:01:59
- -----test.c
#define _set_gate(gate_addr,type,dpl,addr) \
__asm__ ("movw %%dx,%%ax\n\t" \
"movw %0,%%dx\n\t" \
"movl %%eax,%1\n\t" \
"movl %%edx,%2" \
: \
: "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
"o" (*((char *) (gate_addr))), \
"o" (*(4+(char *) (gate_addr))), \
"d" ((char *) (addr)), \
"a" (0x00080000))
上記をgcc -S test.c、にて出力したアセンブリリスト及び、上記をコンパイルしてobjdump -d test.cでのアセンブリリストが違うのですが
どうしてですか?
- 509 :デフォルトの名無しさん:2009/10/23(金) 20:53:19
- 拡張インラインアセンブラについて日本のサイトで色々と解説しているサイトがあれば教えてください。
http://www.mars.sannet.ne.jp/sci10/on_gcc_asm.html#K_SS
ここだけではあまりわからなかったので、
- 510 :デフォルトの名無しさん:2009/10/23(金) 21:48:36
- あれ。。。いつもならすぐにレスが返ってくるのに皆様今日はどうなされたのですか?
- 511 :デフォルトの名無しさん:2009/10/23(金) 23:28:46
- 。。。
・・・
...
・・・
…
- 512 :デフォルトの名無しさん:2009/10/23(金) 23:31:59
- >>511
答えられないなら黙ってなよ
- 513 :デフォルトの名無しさん:2009/10/24(土) 00:09:30
- 三点リーダは二つ重ねるものだ
- 514 :デフォルトの名無しさん:2009/10/24(土) 00:46:35
- #include <stdio.h>
static int local;
int main(void)
{
int in=5, out;
// 256
__asm__("movl $0x100, %edx\n\t");
// 破壊レジスタにedxを設定
__asm__("movl $1, %%edx\n\t"
"incl %%edx\n\t"
"movl %%edx, %0\n\t"
:"=b" (out)
:"a" (in)
:"%edx"
);
// edx = 2になってしまう、期待していた値は256
__asm__("movl %edx, local\n\t");
printf("edx = %d", local);
return 0;
}
破壊レジスタにedxを指定したのですが、拡張インラインアセンブラ内で変化させた値がそのまま表示されてしまいます。
破壊レジスタとは、拡張インラインアセンブラ内にて、この場合edxに変な数値を入れても拡張インラインアセンブラの処理が終われば
元に戻っていうという事ではないのでしょうか?
- 515 :デフォルトの名無しさん:2009/10/24(土) 01:28:24
- warosu
- 516 :デフォルトの名無しさん:2009/10/24(土) 01:46:41
- ...?
- 517 :デフォルトの名無しさん:2009/10/24(土) 09:28:58
- asm文中でレジスタの自動割当する際、指定したレジスタを自動割当しないという宣言。
例をあげると、こう。
# ソース1
int in=1, out;
asm("movl %1, eax; incl %eax; movl eax, %0;" :"=r"(out) :"r"(in));
# 出力1
movl %eax, %eax
incl %eax
movl %eax, %eax
# ソース2
int in=1, out;
asm("movl %1, eax; incl %eax; movl eax, %0;" :"=r"(out) :"r"(in) :"%eax", "%ebx", "%ecx", "%edx", "%esi");
# 出力2
movl %edi, %eax
incl %eax
movl %eax, %edi
なお、全ての汎用レジスタを指定すると、
「冗談は顔だけにしとけよ。割り当てられるレジスタが無いじゃんか。」
とコンパイラが文句を言う。
- 518 :デフォルトの名無しさん:2009/10/24(土) 10:30:50
- #include <stdio.h>
int main(void)
{
int in=1, out;
__asm__("movl %1, %%eax\n\t"
"incl %%eax\n\t"
" movl %%eax, %0\n\t"
:"=r"(out)
:"r"(in)
:"%eax", "%edi", "%ebx", "%ecx", "%edx", "%esi");
printf("in = %d, out = %d\n", in, out);
return 0;
}
破壊レジスタに指定されたeax,edi,ebx,ecx,edx,esiは、
出力オペランド及び入力オペランド(%0,%1)では使用されない
ということでしょうか?
- 519 :デフォルトの名無しさん:2009/10/24(土) 14:54:29
- -Sつけて、asmのソースを見たら
- 520 :デフォルトの名無しさん:2009/10/24(土) 15:06:45
- >>519
見た上で聞いています。
- 521 :デフォルトの名無しさん:2009/10/24(土) 15:19:41
- 何がしたいのかよくわからんのよね
- 522 :デフォルトの名無しさん:2009/10/24(土) 15:28:14
- >>521
:"%eax", "%edi", "%ebx", "%ecx", "%edx", "%esi");
この部分のエラーの事なら察してください
破壊レジスタにeax,edi,ebx,ecx,edx,esiのいずれかを指定した場合は、
出力オペランド及び入力オペランド(%0,%1)の演算等では使用されない
ということでしょうか?
- 523 :デフォルトの名無しさん:2009/10/24(土) 15:33:01
- そうだよ、たぶん。
- 524 :デフォルトの名無しさん:2009/10/24(土) 15:34:56
- >>523
へーそうなんだ
- 525 :デフォルトの名無しさん:2009/10/24(土) 15:48:34
- >>524
模範回答をお願いします。
- 526 :デフォルトの名無しさん:2009/10/24(土) 18:06:20
- >>518
> :"%eax", "%edi", "%ebx", "%ecx", "%edx", "%esi");
察して下さいとあるけど、一応。
この例だと割当可能な汎用レジスタが一つもないから、不可能な指示がある、と
コンパイラが泣き言を言って止まる。
いずれかを指定したならば、明示的・暗黙的を問わず、そのasm文中では破壊しては
いけない用途で使用済みと見なし、%0や%1への割当を行わないだけ。
足りなくなった場合は、使用可能なレジスタの再利用を試み、それが不可能ならば、
やはりエラーを吐いてコンパイル停止する。
- 527 :デフォルトの名無しさん:2009/10/24(土) 18:44:46
- あと、こういう違いがある。
int func(void){
register int i1 = 1;
register int i2 = 1;
asm("addl $1000, %eax;");
i1*=i2;
return i1;}
↑の場合、i1 がeax、i2にedxが割当られてしまい、この関数は1000を返す。
int func(void){
register int i1 = 1;
register int i2 = 1;
asm("addl $1000, %%eax;" :::"%eax");
i1*=i2;
return i1;}
↑の場合、i1とi2にeaxを割り当てるのを避けてくれるから、この関数は1を返す。
- 528 :デフォルトの名無しさん:2009/10/24(土) 19:01:25
- 何がいいたいのか、わからん
- 529 :デフォルトの名無しさん:2009/10/26(月) 21:47:00
- セグメントベースとは、セグメントアドレスに対して*16を行ったアドレスの事ですか?
- 530 :デフォルトの名無しさん:2009/10/26(月) 21:55:54
- ここは学校じゃねえんだ
- 531 :デフォルトの名無しさん:2009/10/26(月) 22:35:35
- >>529
8086の場合のことを言ってる?
- 532 :デフォルトの名無しさん:2009/10/26(月) 23:50:24
- >>529
IA-32では動作モードによって異なる。
16バイト境界に整列することが推奨された32ビットアドレスである可能性もある。
インテルが無料でPDFを配布してるから、それを読んで。
会員登録とか面倒な事は一切無く、日本語で読める文書を無料で配布してくれてるから。
IA-32 インテルR アーキテクチャソフトウェア・デベロッパーズ・マニュアル
下巻:システム・プログラミング・ガイド
上中下巻あわせて4つ、これらはダウンロードしていつでも参照できるようにしておくことが大前提。
- 533 :デフォルトの名無しさん:2009/10/27(火) 01:06:45
- >>532
ダウンロード場所はですか?
- 534 :デフォルトの名無しさん:2009/10/27(火) 01:12:06
- 「インテル 技術資料」でググれ。
- 535 :デフォルトの名無しさん:2009/10/27(火) 01:12:59
- 自助努力を一切しない、できない者に明日は無い。
- 536 :デフォルトの名無しさん:2009/10/27(火) 09:18:52
- 386以降では動作モードによらず内部レジスタであるセグメントデスクリプタキャッシュのセグメントベースとリミットが用いられる
従ってリアルモードでも一応32bitアドレスのアクセスが可能
- 537 :デフォルトの名無しさん:2009/10/27(火) 15:57:28
- >>533
IA-32 インテルR アーキテクチャソフトウェア・デベロッパーズ・マニュアル
↑これで検索すると一発で出てくる。
- 538 :デフォルトの名無しさん:2009/10/28(水) 00:38:52
- 日本語版あったのか…知らなかった
- 539 :デフォルトの名無しさん:2009/10/31(土) 04:08:30
- >>387、>>390-391
ふっつーに、セグメントを跨ぐデータのコピー時には、同じセグメントレジスタだと不都合だからじゃねーの?
>>538
あの資料、少し古い日本語版を良く使っている。
・・・命令セットの章が、PDFを跨いだ分割収録にされる前の物を。
命令セット見るだけならCPUの対応時期も書かれてるからhttp://moon.gmobb.jp/hero/のx86CPU.CHMの方が便利なのかもしれないが、どうなんだろうな。
- 540 :デフォルトの名無しさん:2009/10/31(土) 09:22:14
- セグメントオーバライドプレフィックスで同じセグメントでのコピーにならないっけか?
- 541 :デフォルトの名無しさん:2009/11/02(月) 10:45:04
- 転送元はDS以外を使えるけども、転送先はES固定。
そういや8086はセグメントオーバーライド+REPプレフィックス使うときは
DI/EIで挟む必要があったなー、と今思い出した。
- 542 :デフォルトの名無しさん:2009/11/02(月) 11:40:07
- Z80にもインデックスオーバーライドプレフィクスwがあったな
- 543 :デフォルトの名無しさん:2009/11/02(月) 12:30:40
- セグメントレジスタが違っても同じアドレスを指してることはありうるわけで、
ブロックコピーの範囲が重なる問題には関係ないな。
- 544 :デフォルトの名無しさん:2009/11/02(月) 12:33:29
- >>542
0xddと0xfd?
インストラクションセットにない組み合わせも使えた辺りは確かにオーバライドプレフィックスのようだった。
- 545 :デフォルトの名無しさん:2009/11/03(火) 23:49:40
- ヽ、.三 ミニ、_ ___ _,. ‐'´//-─=====-、ヾ :::::::::/ヽ
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\ :::::::::ゝ‐;----//::::::ヾ.、
|. \ :::}二. \ ::::::::|.r-'‐┬‐l l⌒::::| }
゙l / :: リ ̄ヽ / :::::::|l:::::::::::!ニ! !⌒:://
_______________/ _,ノ':::::::::::::::::ゞ)ノ./
` ー==--‐'´(__,. ..、  ̄ ̄ ̄ :::::::::::::::::i/‐'/ 菊池ビーーーーーーーーーーーーーーーーム!!!
i , .:::υ_,,_,,,,;;-=、ヾ i::::::::::::::::::::l、_/::|
! '!ヽ_=─'''" ,__) !::::::::::::::::::::|:::::::::::|
ヽ. ゙i ::フ二-r──'''",,,,i' ":::::::::::::::::::!::::::::::::::ト、
/ヽ;. |/二/''"''ヽ-‐'" / ,,:::::::::::::::::::::;!::::::::::::::::::::ヽ、
' i |‐、/ / /:::::::::::::::::/:::::::::::::::::::::::::::::ヽ、
/ | |'' ,.‐''i "::::::::::::::/:::::::/::::::::::::::::::::::::::: ^ヽ
" :l !,゙ヽ--‐─‐'''"ノ:::::::::::::::/::::::::/:::::::::::::::::::::::: `ーフ^ゝ〜ヽ、
,イ ..! \_ ,/:::::::::::::/.:::::::/ ::::::::::::::::: :::/ /.:::. `ー-、
-一⌒ `ヽ、 ....:::::::`、 ` ̄"'''":::::::::::;/.:::::::::::/ ::::::: ./、 /.::::. ー
http://changi.2ch.net/test/read.cgi/csaloon/1257171544/299
『騙すンじゃねぇ、ジパング板から来ちゃったじゃねぇか!!』
- 546 :デフォルトの名無しさん:2009/11/04(水) 03:19:55
- LSIC80で8085のコード。ringバッファをXX00番地に配置して、リード・ライトポインタをcharで持つ。
でも ring[rpointer] を参照するにはLXI H,ring で DEreg<--00rpointer を入れて DADする
コードが出ちゃうんだよね。HL<--XXrpointer を入れて MOV A,M するような書式
書けないものかな。
- 547 :デフォルトの名無しさん:2009/11/04(水) 05:29:13
- つ emit
あとは、行儀悪いけど
#define ring 0xXX00
unsigned int hl;
hl = ring | rpointer;
a = *(char *)hl;
とか。
ring[rpointer]は、リンクするまでringの値が確定しないので、
ど〜しても16bit足し算することになるんでないかい。
- 548 :546:2009/11/04(水) 13:39:39
- char*をuintにキャストして or しても、DEに00rpointerを入れて16bitのor演算されちゃいます。
LDA rpointer ; return( ring[rpointer++] ); の最適化
MOV L,A
INR A
STA rpointer
MVI H, HIGH ring
MOV A,M ここまでを_asm_cで書いて、
} にしたらRETは出ました(w
- 549 :デフォルトの名無しさん:2009/11/06(金) 22:54:08
-
あああああああああ
アセンブラを書くとき、MIPSとSHの作り易さは異常
その中でも、俺の中ではSHが一歩リードかな
某スセ社の「プスプ」がMIPSでなくSH採用してりゃもっと良かったのに
RISCのくせに命令が豪華でサイコー
- 550 :デフォルトの名無しさん:2009/11/06(金) 23:00:03
- ttp://science6.2ch.net/test/read.cgi/denki/1189508057/
- 551 :デフォルトの名無しさん:2009/11/06(金) 23:03:54
- 間違えて過疎スレの方貼ってしまった
本スレ
ttp://science6.2ch.net/test/read.cgi/denki/1254737313/
127 KB
[ 2ちゃんねる 3億PV/日をささえる レンタルサーバー \877/2TB/100Mbps]
取りに行ったけどなかった。次は一時間後に取りに行くです。新着レスの表示
掲示板に戻る
全部
前100
次100
最新50
read.cgi ver 05.0.7.8 2008/11/13 アクチョン仮面 ★
FOX ★ DSO(Dynamic Shared Object)