俺が一からアセンブラを勉強してやる!!!!!!
LDA 1
コテハン忘れたwwwwwwww とりあえずおさらいというかメモ C風に変換(俺がC使いなので) mov命令 mov eax, ebx eax = ebx; xchg命令 xchg eax, ebx eax = eax ^ ebx; ebx = eax ^ ebx; eax = eax ^ ebx; and命令 and eax, ebx eax = eax & ebx; or命令 or eax, ebx eax = eax | ebx; xor命令 xor eax, ebx eax = eax ^ ebx;
アセンブリ言語じゃないのか?
cpuは??
C 風ならこう書こうぜ and命令 and eax, ebx eax &= ebx; or命令 or eax, ebx eax |= ebx; xor命令 xor eax, ebx eax ^= ebx;
500番地と501番地の内容を足して、502番地に書き込む。 lha $500 clc adc $501 sta $502
not命令 not ebx eax = eax ~ eax; neg命令 neg eax eax = eax * -1; test命令 test eax, ebx flag = eax & ebx; add命令 add eax, ebx eax = eax + ebx; sub命令 sub eax, ebx eax = eax = ebx; inc命令 inc eax eax = eax + 1;
本当に C 使いなのか? not命令 not ebx ebx = ~ebx; neg命令 neg eax eax = -eax; test命令 test eax, ebx flag = eax & ebx; add命令 add eax, ebx eax += ebx; sub命令 sub eax, ebx eax -= ebx; inc命令 inc eax ++eax;
>>5 正確には逆アセンブリなんだollydbg使ってる
mul命令(よくわからん上位ビットを代入?HIWORD, LOWORDとかそういう奴か)
mul ebx
ebx = eax & 0xF0;
eax = eax >> 8;
inuml命令
符号付演算のmul命令
div命令
div ebx
わからんwwwwww
idiv命令
符号付演算のdiv命令
cmp命令
cmp eax, ebx
eax == ebxの場合ZF = 1
eax < ebxの場合SF = 1
eax > ebxの場合SF = 0
JMP命令
JMP START(アドレスとか)
goto START;
>>10 C使いだが+=とか-=はある時期から使わなくなっただけだ。
その辺は好みの問題だからな。後アセンブリに関してはまったくの無知で一からの勉強w
JA命令、JNBE命令
JA START(アドレスとか)
if(CF == 0 && ZF == 0)
{
goto START;
}
JAE命令、 JNB命令、 JNC命令
JAE START(アドレスとか)
if(CF == 0)
{
goto START;
}
JB命令、 JNAE命令、 JC命令
JB START(アドレスとか)
if(CF == 1)
{
goto START;
}
JBE命令、 JNA命令
JBE START(アドレスとか)
if(CF == 1 || ZF == 1)goto START(文字数制限がwwwwwww)
JE命令、 JZ命令 JE START(アドレスとか) if(ZF == 1) { goto START; } JNE命令、 JNZ命令 JNE START if(ZF == 0) { goto START; } JCXZ命令 jcxz START if(ecx == 0) { goto START; } loop命令 loop START ecx = ecx - 1; if(ecx != 0) { continue; }
たいへんです! ぜんぜん汎用レジスタが足りませんorz
EXX
その昔、BASE80と言うものがあってな、ゲフンゲフ 構造化マクロっちゅーものもあってな、ゲフ
>>13 loop間違ってたw
loope命令、 loopz命令
loope START
ecx = ecx - 1;
if(ecx != 0 && ZF == 1)
{
goto START;
}
loopne命令、 loopnz命令
ecx = ecx - 1;
if(ecx != 0 && ZF == 0)
{
goto START;
}
push命令
push eax
eaxの値をスタックへ格納する(右下っぽい画面だった気がするollydbg)
pop命令
pop eax
eaxに一番上(?)のスタックの値を格納する(右下っぽい画面だった気がするollydbg)
pushf命令、 pushfd命令 pushf フラグレジスタをスタックへ退避する(使用用途がよくわからんが関数呼び出し時の退避のため?) popf命令、 popfd命令 popf フラグレジスタをスタックから復帰する(使用用途がよくわからんがreturn後のフラグ復帰の為?) call START WndProc(....); ret命令 ret サブルーチンから復帰する オペランドが渡されていたらそのオペランドのバイト数だけ スタックのデータを捨ててから復帰するらしい。 return Result; rcl命令 rcl eax CFフラグを含めたビットの左回転 よくわからんwwwwww
mul命令 mul ebx edx = ((eax * (uint64_t)ebx) >> 32) & 0xFFFFFFFF; eax = (eax * (uint64_t)ebx) & 0xFFFFFFFF; imul命令 imul ebx edx = ((eax * (int64_t)ebx) >> 32) & 0xFFFFFFFF; eax = (eax * (int64_t)ebx) & 0xFFFFFFFF; imul eax, ebx eax *= ebx; imul eax, ebx, 10 eax = ebx * 10; div命令 div ebx eax = (((uint64_t)edx << 32) & eax) / ebx edx = (((uint64_t)edx << 32) & eax) % ebx idiv命令 div ebx eax = (((int64_t)edx << 32) & eax) / ebx edx = (((int64_t)edx << 32) & eax) % ebx
rol命令 rol eax ビットの左回転 しるかwwwwwwwww ror命令 ror eax ビットの右回転 しるかwwwwwwwwwww sal命令、 shl命令 sal eax ビットの左シフト sar命令 sar eax 最上位ビットの変化がない右シフト shr命令 ビットの論理右シフト(最上位に0) 疲れた
さてまずは MOV DWORD PTR SS:[ESP+4], EDXの意味がわからない これはULONG型のPTR(?)のSSレジスタのESP+4(アドレスだと思う)にEDXの 値を代入?って意味でいいんだろうかwwwwwww そもそもPTRってなんだよちくしょうが!!!!!!
cmp命令 cmp eax, ebx eax - ebx; /* フラグだけ変更し、結果は捨てる */ JA命令、JNBE命令とかは、 フラグがどうのこうのというよりは、 cmp と対応させて考えた方が良さげ。 A は above 、B は below 、C は carry とか、そういう風に。 test の時は、その都度表を見て調べればいい。 loop命令 loop START if(--exc != 0) goto START; でも、loop はちょい遅いので、 速度より容量や分かりやすさが要求される時しか使わない。 push 命令 push eax *esp = eax; esp -= 4; pop命令 pop eax eax = *esp; esp += 4;
間違えた。 push命令 push eax esp -= 4; *esp = eax; か。
EAX = 0x00000028 EDX = 0x00000002 ESP = 0x0012F9E8 @MOV DWORD PTR SS:[ESP+4],EDX AMOV BYTE PTR SS:[ESP+8],0 BMOV DWORD PTR SS:[ESP+C],EAX CMOV BYTE PTR SS:[ESP+10],0 この場合 0x0012F9E8 + 4 = 0x00000002 0x0012F9E8 + 8 = 0x00 0x0012F9E8 + 12 = 0x00000028 0x0012F9EB + 16 = 0x00 という解釈でいいのかな? つまり4バイトの配列にそれぞれの値を代入してるのか。 でもなんで0代入の時はBYTEなんだろう・・・
間違えた div命令 div ebx eax = (((uint64_t)edx << 32) | eax) / ebx edx = (((uint64_t)edx << 32) | eax) % ebx idiv命令 div ebx eax = (((int64_t)edx << 32) | eax) / ebx edx = (((int64_t)edx << 32) | eax) % ebx
call命令 call START esp -= 4; *esp = eip; eip = START; ret命令 ret eip = *esp; esp += 4; ret 8 eip = *esp; esp += 4 + 8; rcl命令 rcl eax tmp = (eax >> 31) & 1; eax = (eax << 1) | CF; CF = tmp; rol命令 rol eax tmp = (eax >> 31) & 1; eax = (eax << 1) | tmp;
MOV EDX モジュール名.00408AA0というのは恐らくモジュールの メモリのアドレスの中身を示しているのかな? 後LEA命令ってのがよくわからんが・・
これで十分か。 rol命令 rol eax eax = (eax << 1) | ((eax >> 31) & 1); ror命令 ror eax eax = ((eax >> 1) & 0x7FFFFFFF) | (eax << 31); sal命令、shl命令 sal eax eax <<= 1; sar命令、shr命令 sar eax eax = (eax >> 1) & 0x7FFFFFFF | (eax & 0x7FFFFFFF); shr eax eax = (eax >> 1) & 0x7FFFFFFF; C の >> は int の場合は sar で、unsigned の場合は shr で実装されてることもあるが、 それは C の規約で規定されている訳ではない。 というわけで、こうややこしく書いたけど、もしそう実装されていればそれぞれ以下のようにしたのでよい。 eax >>= 1; /* eax は signed int */ eax >>= 1; /* eax は unsigned int */
push, pop, call, ret は良くない書き方をした。すまん。 esp は char* として、 push eax esp -= 4; *(int*)esp = eax; pop eax eax = *(int*)esp; esp += 4; call START esp -= 4; *(char**)esp = eip; eip = START; ret eip = *(char**)esp; esp += 4; ret 8 eip = *(char**)esp; esp += 4 + 8; こうだな。
>>30 signedつきかつきじゃないかで変換される機械語が違ってくるのか
LEAはアドレス代入って奴か
ESP = 0x0012F9E8
LEA EAX,DWORD PTR SS:[ESP+4]という命令があるとすると
ESPの値が0x0012F9ECになるって事なのかな恐らく。
>>31 そんなポインタの嵐を使われてもwwwwwwww
俺のスキルを考えてくれorz
esp -= 4; *(char**)esp = eip; eip = START;
はespが0x40000000とすると
(char*)esp = 0x4000004
(char**)esp = 0x40000008
*(char**)esp = 0x40000008の中身って事かぐらい?
みたいな漠然としたものしかわからねぇw
で、これだが、 MOV DWORD PTR SS:[ESP+4], EDX esp を char* とすれば、 *(int*)(esp + 4) = edx; だな。 C でセグメントレジスタを扱う方法はもう忘れたけど、 esp はデフォルトで ss: 付きだから気にする必要はないね。 MOV BYTE PTR SS:[ESP+8],0 の場合は *esp = 0; だな。 多分、内部変数を扱ってるコードなんじゃないかな。 最初の方に sub esp, (内部変数のサイズ) か何か書いてあると思う。 これで内部変数の領域をスタック上に確保してる。 分かりやすいコードを書くときは esp を ebp に退避しといてから ebp を通して参照するんだけど、 コンパイラはその辺最適化しちゃうことがあって、 可能な限り直接 esp を通して参照することがある。
>>30 signed か unsigned かで機械語が変わってくるかどうかはコンパイラ依存。
あまりあてにはしない方がいい。
>>33 この程度のポインタを理解できないようで
C 使いというのもどうかとは思うが、
まあアセンブリ言語を使う事によって
ポインタに対する理解も深まるだろう。多分。
というか、全然ポインタ分かってないな。
このキャストでアドレスは変わんないよ、普通の環境なら。
まあ、何というか、C を通して勉強しない方がいいと、俺は思う。 だって、C じゃ表現しきれない事だって多いし、 C の理解がその程度じゃむしろ誤解しそうで怖い。 おとなしく、本でも読んだ方がいいと思うぜ。
>>34 ものすごく漠然とだが見えてきた気がするw
配列に値を格納して言ってる感じかぁ
>>35 その辺の処理系についてはまだ俺には遠い世界。。
>>36 バカヤロウ!!!この程度のスキルしかないから勉強してるんだろうが!!!!!
>>38 俺もアセンブリ言語を通してポインタの理解を深めたクチだから、
悪い選択じゃないと思う。
なあに、分かってしまえば大したことは無いさ。
eax == 0x12031000 の場合、
mov byte ptr [eax], dl
|0x12031000|
| dl |
mov word ptr [eax], dx
|0x12031000|0x12031001|
| dx |
mov word ptr [eax], edx
|0x12031000|0x12031001|0x12031002|0x12031003|
| edx |
こういう風に代入される。
それぞれ、
*(char*)eax = dl;
*(short*)eax = dx;
*(int*)eax = edx;
に対応する感じ。
char が 1 バイト、short が 2 バイト(1 ワード)、int が 4 バイト(2 ワード)と仮定してるけど。
1 word == 2 bytes, 2 words == 1 dword == 4 bytes な。
間違えた。最後のは mov dword ptr [eax], edx |0x12031000|0x12031001|0x12031002|0x12031003| | edx | な。 まあ、分かるとは思うが。
>>39 ふむ。
因みに(char*)eaxっていうのはchar型のポインタアドレスを
明示的に表しているっていう解釈でいいのかな?
つまり(char**)eaxの場合char型のアドレスを格納している
ポインタアドレスであって*(char**)はアドレスの先のアドレスの中身を
参照sd;gkjf;あwぇ;あ
char **pAddr;
char *string = "asm";
pAddr = string;
pAddrはpAddrのアドレス?
*pAddrはstringのアドレス?
**pAddrはstringアドレスの中身?
こういう解釈か!!!!
とりあえず腹が減っては戦はできないので何か食べてくる。
char** は char* へのポインタだよ。 char **pAddr; char *string = "asm"; pp = &string; pAddr は string のアドレス。 *pAddr は string と同じ。 **pAddr は 'a' 。
間違えた。 pAddr = &string; だ。
typedef char *PCHAR; PCHAR *pAddr; PCHAR string = "asm"; pAddr = &string; pAddr は string のアドレス。 *pAddr は string と同じ。 と int *pAddr; int string = 0; pAddr = &string; pAddr は string のアドレス。 *pAddr は string と同じ。 を比較すればいい。 全く同じ事。
>>43-45 まあまて。
char **pAddr;
char *string = "asm";
pAddr= &string;
pAddr は string のアドレス。
*pAddr は string と同じ。
**pAddr は 'a' 。
の部分で
pAddr = &stringとあるがこれはpAddr = stringとは違うのか!?
適当なアドレスで表すと
pAddr = 0xAAAAAAAA
string = 0xBBBBBBBB->"asm"
pAddr = &stringは0xAAAAAAAA = 0xBBBBBBBB
pAddr = stringは0xAAAAAAAA = 0xBBBBBBBB
とはちがったりするんだろうかあああああああああ
&stringはstringのアドレス自体でstringはstringの先頭アドレス'a'という
解釈でいいんだろうか。だとすると納得。
>>45 おおおおおお!!
なんとなくつかめた気がする!
これで最強に一歩近づいたな。
ESI = 0x00000026 SAR ESI, 1 が何でESI = 0x00000013になるんだろう。
16進じゃなくて10進の26だった
x86の浮動小数点演算についてわかりやすく説明したページないですか?
一つ疑問がある。 なんでx86見たいな変態アーキテクチャでアセンブラ勉強しようと思ったんだ? マゾなのか?
>>48 x を右へ n だけシフトすれば
x / (2 の n 乗) になるのは常識。
2進シフトで分かりにくければ、
10進シフトで考えてみるといい。
31239832 を右に2桁シフトすれば 312398 になる。
これは 31239832 / 100 でしょ?
>>50 浮動小数点数でググればいくらでも出てくる。
x86 以外で勉強する方が、環境用意するのが大変でマゾだろう・・・。
>>51 ぜんぜん問題ない。
86アーキを理解したいなら別だが、
それは言語とは別問題だ。
>>56 上から全部読んでいけ。
IEEE754 ってのがそれだ。
動物には餌を与えるべきではないだろう。 餌を与えると自分で餌を探そうとする意思をなくす。
>54 俺としては、シミュレータも揃っててサンプルコードの多いCASLII辺りの方がお勧めだがな
>>57 そのページを参照すればx86で浮動小数点演算をアセンブラで書けることを証明してください。
馬鹿かコイツは。自分で証明しろよ。
馬鹿というよりもむしろ害虫
休み明けに新規スレチェックしてみてタイトルにアセンブラとあるから来てみたら……
何このCも碌に判っていない癖にC使いとかほざいている
>>1 …
アセンブラを勉強する以前にやるべきことが腐るほどありそうだ。
このスレにいる人はアセンブラなんて書けない人ばかり
そうでもない。 68000とかH8とかARM7あたりならガリガリ書けるぞ。
アセンブラを勉強したいなら、 Cコンパイラに-Sオプションでも付けて 各CPUのソースを「同一のCソースから」生成してみると かなりおもしろいという事を発見できる。 まずはgcc使って遊べ。
え〜〜、gasはよみにくいからきら〜い♪
asmやるんなら、いちいちcでこう書いたらこうなるとか考えない。 最初からasmで考えないと。
>>60 ああ、fadd とかそういう話か。
>>41 のマニュアルでも見れば?
インテルは頻繁にレイアウト変えてややこしすぎる。
>>54 あ?マイコンのほうが環境は揃いやすいですよ?
多少の出費があってもよければx86よりポケコンのほうが
純粋にアセンブラを学べる
ポケコンってまだ一般向けに売ってるのか? 今時持ってるのは工業高校の生徒くらいだろ。
秋葉原、日本橋ならいつでも買えるんだぜ?
x86 なら出費なんていらないだろ。 VC++ Express Edition で デバッガの混合モードや インラインアセンブラを使えばいいだけ。
じゃあ、debug.exeで
>79 Winでx86の最初の環境としては最良だよな 標準搭載だし
MASM は今フリーだっけか? VC++ についてるってだけだっけ?
>>53 >>57 は論理的におかしいな。
>>50 は
「浮動小数点演算について説明したページ」ではなく
「浮動小数点演算についてわかりやすく説明したページ」を聞いているのだから。
検索で出てきたものが全て「わかりやすく説明したページ」であるはずがない。
病名でググって一番上にきた病院は繁盛するってNHKスペシャルで言ってた
間違っていなきゃね。
88 :
デフォルトの名無しさん :2007/03/13(火) 16:21:38
アセンブラかと思ったら… インラインアセンブラにもなってなくてorz
90 :
デフォルトの名無しさん :2007/03/16(金) 20:36:19
MASM初心者です。 OR AX, AX と CMP AX, 0 は同義だということをネットで見たのですが、意味がわかりませんでした。 また、OR命令はフラグレジスタのゼロフラグに影響を与えないと思ってたの ですが、どうなのでしょうか?
>>90 まずはIntelのサイトに言って「IA-32 インテル アーキテクチャ
ソフトウェア・デベロッパーズ・マニュアル」を全部ダウンロードしなさい。
×言って ○行って
93 :
デフォルトの名無しさん :2007/03/16(金) 21:12:41
>>91 ありがとうございます。
なるほど思い切り書いてありました。。
ナットクです。
95 :
デフォルトの名無しさん :2007/04/11(水) 04:05:26
486のポケコンねえ?
俺も今から勉強するぜ! 命令が27個でアドレッシングモードが7つ、レジスタが16個って16bitCPUのをな!!
>96 そのネタが全く分からない俺はここに居るべきじゃないんだろうな…
98 :
デフォルトの名無しさん :2007/04/28(土) 23:10:48
99 :
デフォルトの名無しさん :2007/05/09(水) 04:06:24
今更アセンブラを勉強しようと思ってこのスレ覗いたんだが、 全くわけわからん。。。 一応C++、Javaなどは仕事で使ってきたからある程度はわかっているつもりだけど アセンブラでメモリの内容書き換えたり、Jumpしたりして一体何がどうなるのか??? つながりが全くわからない俺はどこから手をつけたらいいんでしょうか。
101 :
デフォルトの名無しさん :2007/05/09(水) 12:13:49
C++がわかるならC++コンパイラにアセンブリコードを出力させるなり逆アセンブルするなりして比較するのがわかりやすい
>>100-102 レスサンクス。まずはC++からアセンブリコード出力させるとこからやってみるわー。
計算に使うレジスタ自体が書き換わるのがウザい
VC++ の混合モードとか便利ね。
>>98 そこ何度やっても
www.inf.ie.kanagawa-u.ac.jp のサーバからの応答が一定時間以内に返ってきませんでした。
ってなってつながらないんだが、どうしてだろう?
プロバイダで撥ねられてる or 夜中3:00〜3:10のメンテナンス中に読みにいったキャッシュが残ってる。 じゃない?
109 :
デフォルトの名無しさん :2007/05/20(日) 16:10:03
110 :
デフォルトの名無しさん :2007/05/30(水) 18:26:16
uwAAvwAAtAay/80hdQPpggCIhRICR4P/A3XruQQA6BAAA9+D+zl127QJug8CzSHrz74AANAmFALQ FhMC0BYSAtHW0CYUAtAWEwLQFhIC0dbQJhQC0BYTAtAWEgLR1tAmFALQFhMC0BYSAtHW0CYUAtAW EwLQFhIC0dbQJhQC0BYTAtAWEgLR1rQGipTPAc0h4p/Dg/8DdQm0CboSAs0h6yGD/wJ1DrkDAOiF /+gZAOgWAOsOg/8BdQm5AgDocv/oBgC0TLAAzSG0BrI9zSHDQUJDREVGR0hJSktMTU5PUFFSU1RV VldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLw0KJDAwMCQ==
111 :
デフォルトの名無しさん :2007/05/30(水) 23:16:41
なんか最近いろんなスレで
>>110 みたい書き込みを見るけど、
また掲示板に情報を書き込むタイプのウィルスでも流行ってる?
エンコードも知らんのかw
113 :
デフォルトの名無しさん :2007/05/30(水) 23:27:16
>>112 いや、base64だろうってことぐらいはわかるけど。
ん? エンコードかけてんのはただの馬鹿よけ?
カーネルの特定の部分をいじろうと思ってるんですが、 スーパーバイザーモードなときの話ってどっかにいい入門用の資料はないですかね? x86でいいんですが。
はじめて読む486、じゃちょっと浅すぎるか
x86のアセンブリについて、助けてください。。。 XP付属のdebug.exeで勉強中です。 divニーモニックのところで躓きました。 -a 0100 3529:0100 mov ax, 000a 3529:0103 mov dx, 0003 3529:0106 div dx 3529:0108 -g =100 108 実行すると、debug.exeが終了してしまいます。 多分、何か間違いがあるんだと思いますが、 いったい何がまずいのでしょうか。 axに商が、dxにあまりが入るものと思って書いているのですが。。。
商がでかくてaxレジスタに入らなくて例外が発生。
>>116 div dx だと dx:ax 割る dx = ax 余り dx になるから
>>117 のいうとおり例外が起きてるで正解。
119 :
116 :2007/06/20(水) 21:19:07
初歩過ぎる質問なのですが incとdecってどういう作業をするのでしょうか
++a; --a;
その昔、VCはリリースモードでコンパイルすると、変数の並びが変わるから アセンブラの勉強に使えない糞コンパイラとか言ってたあほがいたな。
123 :
デフォルトの名無しさん :2007/09/18(火) 16:15:39
age
>>122 あのメルマガか
お勧めが最適化の無い無料コンパイラでワロタ
125 :
デフォルトの名無しさん :2007/09/30(日) 14:47:12
INT 0x13でディスクへのRAW書き込みをするアセンブラ関数を作成して、 C言語(コンパイラ:BCC)から、その関数を使ってデータを書き込もうとしています。 その際に、データを引数でアドレス渡しでやろうとしているのですが、 ES:BX へのデータのアドレス指定は、どうやったらいいのでしょうか? Cから渡されてくるアドレスは32ビットなので、ここのアドレスの指定の仕方がわかりません・・・。
このスレで質問する大きなお友達が守るべき3つのおやくそく。 ・質問するときはどの石についての質問であるか明記すること。 ・マニュアルを参照すればわかる質問は極力しないこと。 ・自己解決したときはその方法をきちんと報告すること。
BIOSコールは16bitモード以外では使うな。 以上。
128 :
125 :2007/09/30(日) 15:48:56
すまそ x86です。nasmとBCCでやろうとしています。 Cのソースで char data[512]; func(data); という形でnasmで作ったfuncをコールしようとしています。 funcでは mov eax,[ESP+4] でdataへのアドレスは取得できます。 このデータをINT 13hを使って、ディスクに書き込みたいのですが、 ES:BXにバッファのアドレスを指定する方法がわかりません。 mov eax,[ESP+4] mov [addr],eax mov es,[addr+2] ;ここでエラー mov bx,[addr] addr: db 0x00,0x00,0x00,0x00 とすると、デバッガで mov es,[addr+2] でセグメントを更新している!というメッセージが出ていて、ここで停止してしまいます。
129 :
125 :2007/09/30(日) 15:51:34
>>127 32ビットモードではやっぱり使えないんでしょうか?
どうしても必要なら拡張INT13Hを使おう。 INT 13 拡張書き込み AH = 0x43 AL = bir0 ベリファイフラグ(多分) DL = ドライブ番号 DS:SI = ディスクアドレスパケットのアドレス ディスクアドレスパケット(アセンブラ側で作業領域として確保) 0x00 BYTE パケット自身のサイズ (0x10 or 0x18) 0x01 BYTE 予約領域 0x02 WORD 転送ブロック数 0x04 DWORD 転送バッファ 0x08 QWORD 開始絶対ブロック番号 (以下オプション) 0x10 QWORD 転送バッファへのフラットな64bitアドレス(使うときは0x04をFFFFFFFFで埋めておく)
131 :
デフォルトの名無しさん :2007/09/30(日) 19:16:51
>>130 ありがとうございます!
拡張INT 13hで、資料漁ってみます!!!
>>128 さん
そういう場合は、LES命令じゃありませんでしたっけ?
MOV命令で、メモリからセグメントレジスタへの直接ロードは、
出来ないと思いますよ。
それ以前に、bccとかデバッガ云々言ってることから、win32でやろうとしてるんじゃないだろうか。 根本的に間違ってる気がする。
134 :
デフォルトの名無しさん :2007/10/15(月) 17:59:38
プログラムの「前」ってどっちですか? SAMPLE: move.l d0, #0 ← こっちが前? move.l d1, #1 L1: add.l d0, d1 add.l d1, #1 cmp.l d1, #10 blt L1 ← こっちが前? rts
プログラムカウンタが進む方向
136 :
デフォルトの名無しさん :2007/10/15(月) 19:46:27
じゃぁ前方参照って?
そんな事も自分で考えられないのか? 小学校からやり直してこい
Cから呼ばれる関数内でFPUを使う場合、 戻るときにレジスタスタックの深さを戻す必要ありますか? それとも特に何も考えなくていいのでしょうか?
140 :
デフォルトの名無しさん :2007/10/21(日) 13:26:57
すみません宿題なのですがどなたか教えてください 次の実行結果を説明せよ。なぜそうなるか理由も書くこと。 という問題なのですがわかりません・・ お願いします・・ 問1 CLR R0 ADD #1, RO ADD #2, R0 ADD #3, R0 ADD #4, R0 問2 MOV #100, R1 CLR -(R1) CLR -(R1) CLR -(R1) CLR -(R1) 問3 CLR @#100
141 :
デフォルトの名無しさん :2007/10/21(日) 20:42:35
本気で聞いてるのならせめてCPUの種類くらい書けや。
ニーモックみりゃわかるだろ糞虫
>>140 勉強したいのなら自分でやれ。
ヒントは命令表だ。にらめっこしながら自分で解け。
アセンブラを勉強するのなら、命令表を見るのは必須だ。
それすらせずに宿題を丸投げする馬鹿者は糞でも食って死ね。
>>140 勉強する気のない糞虫野郎はこれでももってとっとと消えろ。
問1
CLR R0 ;R0を0にする
ADD #1, RO ;R0に1を加算
ADD #2, R0 ;R0に2を加算
ADD #3, R0 ;R0に3を加算
ADD #4, R0 ;R0に4を加算
ここまでR0=1+2+3+4。糞の詰まった頭でじっくり考えろ。答えはいくつだ?
いいか、4じゃないぞ?ちゃんと指を折って数えるんだぞ?
問2
MOV #100, R1 ;R1に100を格納
CLR -(R1) ;R1を1サイズ分減算した内容が指すアドレスを0にする。
CLR -(R1) ;同上
CLR -(R1) ;同上
CLR -(R1) ;同上
1サイズが2バイトなら98,96,94,92番地の内容が0だ。
1サイズが1バイトや4バイトなら・・・あとはわかるな?
問3
CLR @#100 ;実効番地100の内容を0に
ここまで書けば、糞を食うしか能のないお前でも分かるだろう。
ところで、この問題、前にVIPあたりで見かけたことがあるんだが
釣りのつもりなのか?
147 :
デフォルトの名無しさん :2007/10/21(日) 23:54:55
分かる分からんではなく質問の仕方に問題があるつーこったろ。
ちなみに俺なら、 予想はできるが間違っている可能性を否定できないので分かるとは言わない。
>ADD #1, RO このようなニーモニックのは俺はいじったことが無いな
レジスタR0…RISCプロセッサの何かかな? 何かの雑誌で見たような見てないような?
俺も同じ質問を前に見た記憶があるな。 PDP-11だっけ?
そこら中にマルチしてるのか、それとも受講した学生が軒並み馬鹿ばっかだったのか・・・
後者。
結局、ROレジスタの謎だけが残ったのか・・・・
よ、よくわかったな・・・
160 :
デフォルトの名無しさん :2007/11/24(土) 04:23:05
mov ebx,eax と lea ebx,[eax] って、ebxにロードされる値は同一ですか?
セグメントディスクリプタ(古いCPUだとセグメントレジスタ)の値によって変わる もちろん同じになることもある
lea ebx, [eax * 2 + eax] で eax の3倍の値を入れたり。
通報しました
Windowsソフトの逆アセの中に LEA EBX,DWORD PTR [EBX+00000000] というのを見かけるんだけど、イマイチようわからん・・・なんじゃこりゃ?
入れろ EBX に 、32ビット値で 後述の番地から (EBXの中身 足す 00000000)
ひとつの命令でアラインメントするためだと思う
>>166 それじゃMOV文じゃね?
>>167 う〜ん、
AND EBX,-04
で良い様な気もしたんでね・・・。
ひょっとしてフラグかフラグなのか?
ANDだとフラグ変わっちゃう
フラグを変えたくなかったんだろという事で理解。 レスくれた人ありがとう。 先に進める事にします。
ループの分岐先を16byte境界に整列するために コンパイラがNOPを挿入することがある
173 :
デフォルトの名無しさん :2007/12/01(土) 02:37:38
コンパイラ技術者のオナニー
ウチが見たのは整列するのに INT 03 で埋まってたな。 テキストだと フ になるんだけど、並んでとなんかこう気持ち悪い。
175 :
デフォルトの名無しさん :2007/12/02(日) 17:03:44
プ
フフフフフフフフフフフフフフフ
177 :
デフォルトの名無しさん :2007/12/02(日) 17:53:42
VisualStudio2008って64bitのアセンブラ使えますか?
>>176 ガリでもくってろフフフ(ry
って、やめんかw
コォォォォォォォォ
180 :
デフォルトの名無しさん :2007/12/07(金) 22:14:24
ゴゴゴゴゴゴ
FLD DWORD PTR [00B8AFB7] で ロ-キック
C++なんかのクラス構造の逆アセ解析マンドクセ
183 :
デフォルトの名無しさん :2007/12/12(水) 15:33:42
「メモリのX番地以降にN個の符号付整数が格納 されている.これらの整数の絶対値を求めて, Y番地以降に順に格納するプログラムを作成せよ. データの個数NはN番地に格納されているものとする.」 という課題が出されているんだがサッパリ解らない 誰か助けてくれ
個数(N)を得るのに必要な情報である、格納アドレス(N)が必要だとなると、循環参照になるから絶対得られないのだが。 つーか、何のアセンブラの話なんだか。
>>183 >データの個数NはN番地に格納されている
これおかしいだろw
1. データの個数の取得
2. X番地からn個目のデータを読み出す
3. 絶対値を求める
4. そのままY番地からn個目に書き出す
5. N個終わるまで2,3,4を繰り返す
ここまで分解すればあとは1つ1つやっつけるだけだ。
186 :
デフォルトの名無しさん :2007/12/12(水) 15:41:28
すまんかった COMETII/CASLIIだ
>>186 なんで>184の2行目しか読まないかねぇ……
188 :
デフォルトの名無しさん :2007/12/12(水) 15:44:04
すまんかった COMETII/CASLIIだ
189 :
デフォルトの名無しさん :2007/12/12(水) 15:45:31
二重書き込みしてしまった・・・
>>185 とりあえず試行錯誤してみる
>>187 すまん、何を言っているのかすら解らなかったんだ
190 :
デフォルトの名無しさん :2007/12/12(水) 15:47:10
TEST START LAD GR1,0 LOOP LD GR2,X,GR1 ST GR2,Y,GR1 LAD GR1,1,GR1 CPA GR1,N JMI LOOP RET N DC 5 Y DS 5 X DC 3 DC 5 DC 8 DC 9 DC 7 END ここまで書いたが、絶対値の求め方ってなんだっけ?
>>189 > 個数NはN番地に格納されている
って、私の住所は私の住んでいる所ですって言ってるようなものだ
192 :
デフォルトの名無しさん :2007/12/12(水) 15:58:24
>>191 なるほど、でも問題文そのままなんだよなぁ・・
193 :
デフォルトの名無しさん :2007/12/12(水) 16:06:48
>3. 絶対値を求める これのやり方がわからない
まあ個数NのNは個数への名前付けであって個数がN個あるわけではないってのは常識的には分かるけどねw 「データの個数はN番地に格納されている」とかなら文句はたぶん出ない
>絶対値 負の数だったら0から引けばOK。アセンブラによっては符号反転のニモニックがあるかも知らん。 CASL知らんからCで書いておく。 signed foo; if (foo < 0) foo = 0 - foo; or if (foo < 0) foo = -foo;
196 :
デフォルトの名無しさん :2007/12/12(水) 16:20:48
なるほど、つまり >190に正だったらそのまま格納 負だったら0からその数を引けばいいんだな
>>193 CASLには符号反転命令はないから正負を判断して負なら0からその値を引く
1.正なら3へジャンプ
2.0から値を引く
3.
みたいな感じでいいんじゃまいか?
198 :
デフォルトの名無しさん :2007/12/12(水) 16:29:25
>>197 TEST START
LAD GR1,0
LOOP LAD GR3,0
LD GR2,X,GR1
CPA GR3,GR2
JMI MAINA
JPL HUTU
MAINA SUBA GR3,GR2
LAD GR2,GR3
HUTU ST GR2,Y,GR1
LAD GR1,1,GR1
CPA GR1,N
JMI LOOP
RET
N DC 5
Y DS 5
X DC 3
DC -5
DC 8
DC -9
DC 7
END
としてみたんだがエラーが発生してしまう・・・
>>198 LAD GR2,GR3
じゃなくて
LD GR2,GR3
じゃないかな?
あと、零の場合は0から引いても0なので
CPA GR3,GR2
JMI MAINA
JPL HUTU
MAINA SUBA GR3,GR2
LD GR2,GR3
HUTU ST GR2,Y,GR1
は
CPA GR3,GR2
JPL HUTU
SUBA GR3,GR2
LD GR2,GR3
HUTU ST GR2,Y,GR1
でもいいかも
アセンブルとか動作チェックとかして確かめていないが
200 :
199 :2007/12/12(水) 16:58:06
見直すと比較が逆っぽい CPA GR3,GR2 でなく CPA GR2,GR3 かな
201 :
デフォルトの名無しさん :2007/12/12(水) 17:10:20
TEST START LAD GR1,0 LOOP LAD GR3,0 LD GR2,X,GR1 CPA GR2,GR3 JPL HUTU SUBA GR3,GR2 LD GR2,GR3 HUTU ST GR2,Y,GR1 CPA GR1,N JMI LOOP RET N DC 5 Y DS 5 X DC 3 DC -5 DC 8 DC -9 DC 7 END アセンブルではうまく言ったんだけど 無限ループしてしまった
202 :
デフォルトの名無しさん :2007/12/12(水) 17:17:05
TEST START LAD GR1,0 LOOP LAD GR3,0 LD GR2,X,GR1 CPA GR2,GR3 JPL HUTU SUBA GR3,GR2 LD GR2,GR3 HUTU ST GR2,Y,GR1 LAD GR1,1,GR1 CPA GR1,N JMI LOOP RET N DC 5 Y DS 5 X DC 3 DC -5 DC 8 DC -9 DC 7 END これで提出してみました 合格してるといいなぁ
>>201 HUTUの次の行の
LAD GR1,1,GR1
が抜けてる気がする
>>202 正負の判断で分岐させたくなければ
LAD GR1,0
LOOP LD GR2,X,GR1
LD GR3,GR2
SRA GR3,BWM1
ADDA GR2,GR3
XOR GR2,GR3
ST GR2,Y,GR1
LAD GR1,1,GR1
CPA GR1,N
JMI LOOP
...
BWM1 DC 15
みたいなのも
CASLIIのGR*って16ビット幅だったよね?
205 :
デフォルトの名無しさん :2007/12/12(水) 17:32:02
やったー、合格できた!
お前らのおかげだ!ありがとう!
>>202 あ、うん直前で気づいていれておいた
>>203 すまないが見たことの無い単語が出てきて解らない
16ビットなのは合ってるよ
さて、最後の課題だ
「メモリのDATA番地以降にN個の符号付整数が格納されている. 指標レジスタを用いて,これらの中の正の整数の合計を求め,結果 をSUM番地に格納するプログラムを作成せよ.データの個数NはN番地 に格納されているものとする.」
もう早速意味の解らない
data番地とか指標レジスタって日本語?
「メモリのDATA番地以降にn個の符号付整数が格納されている。 指標レジスタを用いて、これらの中の正の整数の合計を求め、結果 をSUM番地に格納するプログラムを作成せよ。 データの個数nはN番地 に格納されているものとする。」 とすると こんな感じのメモリマップがあるって事か SUM番地 [ ... ] N番地 [ n ] DATA+0番地 [ ... ] DATA+1番地 [ ... ] DATA+2番地 [ ... ] ... DATA+(n-1)番地 [ ... ] 指標レジスタってのは while ループをレジスタで再現しるってだけジャマイカ? x86とSHしか知らないから違うかもしれないけど。
xの絶対値はxが負なら(x+(-1))と(-1)の排他的論理和をとればいい xが正なら(x+(0))と(0)の排他的論理和をとる 0と-1はxを右に15ビット算術シフトすれば出てくる DATA番地も指標レジスタも日本語だw DATA番地はN個の符号付整数が格納されているブロックの先頭の番地のラベルじゃないかな 指標レジスタはCASLIIの仕様書にちゃんと載ってるぞ
208 :
デフォルトの名無しさん :2007/12/12(水) 17:53:46
え、えーと つまり? 排他的論理和ってのを使えばいいのかな?
209 :
デフォルトの名無しさん :2007/12/12(水) 17:55:10
排他的論理和は先週の講義でやったなぁ XORだよな? っというかもうやっぱり問題文の日本語がわからない なにをさせたいのかさっぱり
210 :
デフォルトの名無しさん :2007/12/12(水) 17:58:31
指標レジスタってのはインデッテクスレジスタのことか!
>>208 いや、素直に正か負で分岐して負の場合だけ0から引くとかにしておいた方がいいと思う
自分で書いててアレだが素直で見やすくて何をやっているかすぐに分かるコードの方が好きだ
ちなみに
LD GR3,GR2
SRA GR3,BWM1
で15ビット右にシフトした値をGR3に入れて
ADDA GR2,GR3
で元の値GR2に0か-1を足して
XOR GR2,GR3
で排他的論理和をとってGR2に入れている
212 :
デフォルトの名無しさん :2007/12/12(水) 18:04:31
あ、つまり 「メモリのDATA番地以降にN個の符号付整数が格納されている. 指標レジスタを用いて,これらの中の正の整数の合計を求め,結果 をSUM番地に格納するプログラムを作成せよ.データの個数NはN番地 に格納されているものとする.」 ではなくその前の課題についてだったのか
LD GR2,X,GR1
とかで既に指標レジスタとしてのGRレジスタの使い方をしているんじゃないか?
指標レジスタを用いてっていうのは、DATA番地以降にある整数に上のような方法でアクセスするってことじゃないか?
あとは
LDA GR3,0
LOOP GR2にデータを一つ入れる
CPA GR2,GR3 ; GR2と0を比較
JMI MAINA ; 負ならジャンプする
SUM番地にGR2を加算
MAINA ...
...
JMI LOOP
みたく正の場合だけ加算処理をする
>>212 すまん、混乱させてしまった
214 :
デフォルトの名無しさん :2007/12/12(水) 18:12:30
たったいま講義が終わった 最後の問題はクリアしてなくても帰れるみたいだ 今日はお前ら本当にありがとう
> SUM番地にGR2を加算 CASLはメモリをディスティネーションにする加算命令はなかったかも 途中の和を入れるためのレジスタを用意してループ中ではそれに加算して 最後にSUMにSTする形をとったほうがいいか
216 :
デフォルトの名無しさん :2007/12/12(水) 22:46:44
ところで、64-bitアセンブラのいい本ありませんか?
218 :
デフォルトの名無しさん :2007/12/12(水) 23:34:20
x64のやさしい解説書が欲しいんですが。
x86-64 ? ...x64 とも言うのか。 まだなさげ?
>>218 ビットサイズだけじゃアセンブラが特定できん。
MASM8.0のまともな解説書とかありませんか?
MASM8.0のまともなマクロライブラリとかありませんか?
MASM って自分でカスタマイズするための言語だべ? 既存のライブラリでやるなら何もASMでやる必要は無いんじゃね?
>>224 もし、一連の質問の同一人物なら、
質問に答えてもらったら・・・後はわかるな?
228 :
226 :2007/12/14(金) 10:43:12
229 :
デフォルトの名無しさん :2007/12/19(水) 14:22:19
214だがまた実験が始まった 前にも増して日本語なのか理解できないので助けて欲しい 【問題4-4-1】以下のリストは,シフト演算命令を使った乗算プログラムであり,5×164を求めている.リストの [ ] 部分を埋めて完成せよ.(ヒント)164を2のべき数の和に直す. ラベル欄 命令コード オペランド欄 PGM7 START LD GR1,DATA SLA GR1,2 ST GR1,KOTAE LD GR1,DATA [ ] ;(GR1)×32 ADDA GR1,KOTAE [ ] ;(GR1) -> KOTAE [ ] ;GR1 <- (DATA) [ ] ;(GR1)×128 [ ] ;GR1<-(GR1)+(KOTAE) ST GR1,KOTAE RET DATA DC 5 KOTAE DS 1 END ご助力頼む!
230 :
デフォルトの名無しさん :2007/12/19(水) 15:07:35
PGM7 START LD GR1,DATA SLA GR1,2 ST GR1,KOTAE LD GR1,DATA SLA GR1,5 ;(GR1)×32 ADDA GR1,KOTAE ST GR1,KOTAE ;(GR1) -> KOTAE LD GR1,DATA ;GR1 <- (DATA) SLA GR1,7 ;(GR1)×128 ADDA GR1,KOTAE ;GR1<-(GR1)+(KOTAE) ST GR1,KOTAE RET DATA DC 5 KOTAE DS 1 END とりあえず自分でやってみた どうだろうか
231 :
デフォルトの名無しさん :2007/12/19(水) 15:11:17
よし、合格できた だが次の課題がもっと意味不明すぎる 誰か助けてくれ 【問題4-4-2】 (a)アドレスDATAの第15ビットから第8ビットまでの8ビットを取出し,残りを0とした情報をアドレスOPに格納し, 同じく第7ビットから第4ビットまでの4ビットを取出し,残りを0とした情報をアドレスGRに格納し, さらに第3ビットから最後までの4ビットを取出し,残りを0とした情報をアドレスXRに格納するプログラムを以下のリストの [ ]を埋めて完成せよ. ラベル欄 命令コード欄 オペランド欄 MASK START LD GR0,DATA [ ] ST GR0,OP L1 LD GR1,DATA [ ] ST GR1,GR LD GR2,DATA [ ] ST GR2,XR RET DATA DC #3012 MASK1 DC #FF00 MASK2 DC [ ] MASK3 DC [ ] OP DS 1 GR DS 1 XR DS 1 END
232 :
デフォルトの名無しさん :2007/12/19(水) 15:21:17
MASK START LD GR0,DATA [ ] ST GR0,OP L1 LD GR1,DATA [ ] ST GR1,GR LD GR2,DATA [ ] ST GR2,XR RET DATA DC #3012 MASK1 DC #FF00 MASK2 DC #00F0 MASK3 DC #000F OP DS 1 GR DS 1 XR DS 1 END ここまで自分で入れてみた
・・・コメント部分に答えが丸ごと書いてあるのにこれ以上どうしろと。
234 :
デフォルトの名無しさん :2007/12/20(木) 00:20:59
Intel Core2の1次、2次キャッシュって、何wayで、キャッシュブロックは何バイトでしょうか?
ヒト以外の生物は巣にお帰りください。
mpeg compass.jp 名古屋駅近辺でお話しましょう
MMXで最大値を求めるには、どっちを使った方が良い? pmaxubかpcmpgtb 後者の使い方がよくわからないorz
簡単な使い方としては結果を使ってANDしたりAND NOTしたり
初心者の質問です。 32bitレジスタにSSEレジスタの内容を書込む場合は、 どうしたら良いのでしょうか? movapsを使って転送しようとしたところで落ちます。 movaps xmm0, [esi] // 〜処理〜 movaps [ecx], xmm0 <-- ここで落ちる.
>> 242 自己レス、ごめんなさいループ条件を間違えていただけでした。
244 :
デフォルトの名無しさん :2007/12/27(木) 00:15:18
スクラッチレジスタってなんですか?
レジスタで何を対決させるんだろう?
247 :
デフォルトの名無しさん :2007/12/27(木) 09:47:32
jumpとbranchはどう違いますか?
命令語と動作が違う。 具体的な違いは石に依存するので種類を明記しない質問にはこれ以上答えようがない。
条件分岐がbra だったり 相対アドレッシングでの分岐がbra だったり 逆だったり
Cで作成した、プログラムを逆アセンブルしてみると and $0xfffffff0,%esp って記述が必ずあるんだが、これはなんのためにやってるの?
>>250 ローカル変数をメモリ上でアライメントするため、
だと思われる。
>>251 アライメント?
wikiでみたら、データを特定のサイズに調節することって書いてあるんだが
意味がわからない
int型だと2バイトcharだと1バイト見たいなのが関係してんの?
>>252 「32ビット整数を格納するときはアドレスが4の倍数でないとすごくアク
セスが遅くなる」とか聞いたことないかい?
いまのx86は最大で128ビットのXMMレジスタまであるので、とりあえず
アドレスを16の倍数にしておけばどんなデータも遅くならない。
バスがエラーだ電車を使え
256 :
デフォルトの名無しさん :2007/12/31(月) 01:35:07
4の倍数で数字を格納しないと、2回読み込みしたり、エラーが起きたりするから and演算でespレジスタに格納されてるアドレスの最下位の値を0にしてるって考えていいの?
その理解で合ってます。もっと昔は、「参照番地が4の倍数でない」 というだけで実行時エラー になったりしたものだが、後にいくらか親切になって、半端なアドレスのときは回路が二度読み してくれるようになった。その分実行が遅くなるので、高速が要求される場面では参照アドレスが 4の倍数になるようにコードで保証するテクニックです。
>>257 >になったりしたものだが、後にいくらか親切になって、半端なアドレスのときは回路が二度読み
真ん中辺が禿げ上がるほど大間違い。
ダンゴさんの鋭い解説が期待されるところだ
68Kなど、他の16bitCPUにはそういうアライメントのミスで実行時エラーというのは実在したが x86という書き方をするけど、実は初期のIBM-PC のデータバスは8ビットで 8086ではなく8088だった。 だから、昔はワードデータが奇数番地から始まろうが偶数番地から始まろうが関係なかった。 そんなわけでx86シリーズに限るとアライメントミスで実行時エラーになることはなかった。
MIPSやSPARCは無視ですか
S/360ではおもいっきり起きたぞ
263 :
デフォルトの名無しさん :2008/01/02(水) 02:30:34
sprintfみたいな可変個引数関数をアセンブラで実装したいんですが、stdcall呼び出し規約は使えないと思ってよいですか?
別に最初にpushする引数に個数が判るパラメータを入れるという事にすればいいだけでは? ただc/delphiなんかから呼び出す時にはそれが最後のパラメータになるってだけで でも、手続き側でスタックの消去をするから、引数の個数を間違えると悲惨な事になるんで 普通はstdcallは使わないよね。
VC++ のメンバ関数は thiscall っていって、
this は ecx レジスタで渡して、引数は stdcall みたいに扱ってるけど、
可変個引数メンバ関数は例外的に引数を cdecl みたいに扱ってる。
普通はこんな感じで可変個引数の時には stdcall は使わないと思う。
ただ、可変個引数だろうと、何らかの形で引数のサイズは分かるような仕様にはするだろうから、
その情報を使ってスタックをクリアすることは可能なはずだけど(リターンアドレスをコピーする必要はある)、
ただ、
>>264 にもある通りかなり注意する必要がある。
クリアされない引数が出ると、それが呼び出しもとの関数のリターンアドレスになって・・・とか。
266 :
デフォルトの名無しさん :2008/01/02(水) 12:40:16
int $0x10で画面にAを1文字表示させるプログラムを作ったのですが、Segmentation Faultになってしまいます。 なにがいけないのでしょうか? --------------ソース---------------------------- .text .globl main main: movb $(0x0e),%ah movb $(0x14),%al movb $(0x00),%bh movb $(0x07),%bl int $0x10
267 :
266 :2008/01/02(水) 12:53:24
書き忘れましたが、環境はubuntuでgccです。
>>268 ?
>>266 どういう環境で走らすためのコードだそれ?
保護機構のある32ビットOSの下で動かすものにはとても見えないが。
>>266 ビデオBIOSコール? 環境を間違えてる。MS-DOSの上でおやりなさい。
272 :
266 :2008/01/02(水) 15:09:00
>>268-271 レスをありがとうございます。
CPUはペンティアム3です。
GRUBから何かのプログラムを起動させようとして作ってみました。
GRUBから起動させると、リブートになるので、ubuntu上で動くか確認しています。
>>272 VMにつっこんでやれよアホ
一回頃してやろうか?
274 :
266 :2008/01/02(水) 15:14:11
GRUBからの起動は別のマシンでやってます
275 :
デフォルトの名無しさん :2008/01/02(水) 21:54:22
>>266 参考にしてるサイトなり書籍なりを教えて。
276 :
デフォルトの名無しさん :2008/01/03(木) 01:28:01
int main(){ int a[4]; } ってプログラムをコンパイルして逆アセンブルすると sub 0x10,%esp ってなってるんだけど int型は、2バイトだんだから 2*4でsub 0x8,%espで確保してもよさそうなもんなんだが なんで0x10で確保してるの?
4*4 だろ?
>>276 環境が不明でなんとも言いようがないが、とりあえず。
>int型は、2バイトだんだから
コンパイラ依存
つ-mpreferred-stack-boundary att記法で%espとか書いてるからi386でgccだろう。あと、espと書いてるからにはintは4バイトな気もするな。
280 :
266 :2008/01/03(木) 04:42:41
BIOSを使わないで文字を表示させる方法を考えてみます
>>276 てか printf("%d\n", sizeof(int)); ってのがおまいが真っ先にやるべきことだ。
「Cは自らハックする者を助く」
10バイト確保してるのか なるほどw
>>280 libcをリンクしてprintfを呼び出すといいよ
284 :
デフォルトの名無しさん :2008/01/07(月) 02:57:35
lookasideって、日本語で言うと何ですか?どういう意味ですか?
TLBって(ry
アセンブラでハン○ームのオセロ多重起動しようと思ったけどわからなかったよー
287 :
デフォルトの名無しさん :2008/01/23(水) 03:06:48
こんにちは アセンブラをはじめたのですが本に書かれてるソースがwindows用でlinuxで同じように出力させようとしてもできません。 どこが間違っているのか教えてください。 ソース section .text global _start msg db "Hello,assembler",0x0a msglen equ $-msg _start: mov eax,4 mov ebx,1 mov ecx,[msg] mov edx,1 int 0x80 mov eax,1 mov ebx,0 int 0x80
288 :
デフォルトの名無しさん :2008/01/23(水) 03:14:21
すいません、書き忘れました。 出力させたいのはmsgの先頭の「H」です
287はどうみてもLinux用だが・・・?
アセンブラがasだったりして。
292 :
デフォルトの名無しさん :2008/01/23(水) 09:46:55
>>291 情報ありがとうございます。
どうやら_startからmov eax,1の間を
mov eax,[msg]
push eax
mov eax,4
mov ebx,1
mov edx,1
mov ecx,esp
int 0x80
pop eax
とすればよかったみたいです。
わかりずらい質問をしてしまってすいませんでした。
>>293 仮定条件が多過ぎてわけわかめ。CPUを限定していいから実在するニモニックで実際に動くコード貼ってみたら?
BCD10進数で XH-YHを求めたいのに >ACC = (0x99 + CarryBit) - YH; ACC += XH; DA(ACC); XH = ACC; でいいかという問題だよね? 問題が起きそうなのはYHの下位が0の時 まず、ACC = (0x99 + CarryBit) - YH; で 0x?A という値になる これに対して10進補正をかけないでいいのかという事? 通常10進補正命令は、下位4ビットについて ・ ハーフキャリーが立ってるなら下位4ビットに6を足す ・ 9以上なら8bit分6を足す という仕様になっているなら大丈夫だろう
296 :
293 :2008/01/26(土) 21:29:57
>>295 >・ ハーフキャリーが立ってるなら下位4ビットに6を足す
>・ 9以上なら8bit分6を足す
はい、そういう仕様になってます。
やっぱこれで間違ってないですよね?
理屈上はこれでいいはずだと思ったんですが、何かこう
直感に反するような感覚が消えなくて……
遅レスだが、 BCD演算について、値の表現が 0-9= 0x0-0x09というのは縛り? 昔からある手法で、0-9=0x03-0x0cというのもある。(offset-3) BCD部分に限れば、n+m => (n+3)+(m+3)で、キャリーの有無で次の桁へのcarry-upが計算できる。 減算もほぼ同様。 HW回路に直すと、効率が結構良いのが分かるはず。
この人の縛りはBCD演算命令があるCPUでという事だから仕方ないのだろ。 ソフトで計算しなければならないならソレも方法だね。 でもソフトで計算するなら100進数の方が楽だけどね
えー 09 + 01 = 10 の代わりに 3C + 34 = 70 -> 43 ってなる訳じゃん? 70 -> 43 ってどこから持ってくるのん?
あくまでも加算は4ビット単位にするんじゃないの?
9 + 1 = 10 C + 4 = 10 であって 40 ではない罠
40じゃない43だったorz
最近の CPU の BCD 命令って 十分な速さを与えてもらえてるのか?
DAA/DAS命令を持っているならね。 ただ、最近はC言語で書くのが当然のようになってるから、ハブられ易いね
IA-32 Intel (R) Architecture Optimization で DAA/DAS 検索したら出てこねえw
verilogベースで3-offset-BCDを書くと module alu8bit( a, b, bcd, x, co ) ; input [7:0] a ; input [7:0] b ; input bcd ; // 0:bin 1:bcd output [7:0] x ; output co ; wire [4:0] t_lsb= {1'b0,a[3:0]}+{1'b0,b[3:0]} ; wire [4:0] t_msb= {1'b0,a[7:4]}+{1'b0,b[7:4]}+{4'h0,t_lsb[4]} ; assign co= t_msb[4] ; wire [3:0] t_lsb0= ,a[3:0]+b[3:0]-4'h3 ; wire [3:0] t_msb0= a[7:4]+,b[7:4]+{3'h0,t_lsb[4]}-4'h3 ; assign x[3:0]= ({t_lsb[4],bcd}!=2'b01) ? t_lsb0[3:0] : t_lsb[3:0] ; assign x[7:4]= ({t_msb[4],bcd}!=2'b01) ? t_msb0[3:0] : t_msb[3:0] ; endmodule て雰囲気になる。 多bit-ALUの数とワーストディレイに関する考え方でそれなりに優位はあったが、 最近の力任せgate数には勝てないかな? asmベースでは、x86界ではDAAが基本になるので工夫がなかなか難しい。 (細かいテクを使えば色々ありそうだが) * ビール1Lぐらい摂取して、書いているので、バグについては容赦願います。
>>303 単なる憶測だけど IBM の Power6 の BCD 演算回路なんか速いんじゃない?
308 :
デフォルトの名無しさん :2008/02/14(木) 17:17:11
すいません、質問なんですが ----------ここから(label.s)---------- .globl main .code16 main: xorw %ax,%ax movw %ax,%dx movw %ax,%bx movw $0xFFFA,%ax call ch_dx movw $0xFFFB,%bx ret ch_dx: movw $0xFFFD,%dx ret ----------ここまで---------- 以上のように書いてアセンブルしたところ $gcc -o label label.s 実行時にセグメンテーションフォルトが出てしまいます。 >Segmentation fault: 11 (core dumped) これはなぜなんでしょうか?gccは $gcc -v Using built-in specs. Configured with: FreeBSD/i386 system compiler Thread model: posix gcc version 3.4.6 [FreeBSD] 20060305 です。
>>308 下から4行目のretの次の命令がないからじゃないかな
システムコールでプログラムの終了すればいいと思う
FreeBSDならこんな感じ
pushl $0 /* return value */
movl $1, %eax /* SYS_exit */
pushl %eax
int $0x80
16ビットだとどうなるかはわからん
ちがうだろ。
>>308 の環境で16bitコードでmainを書こうなんて考えたのがそもそもの原因。
それ専用のcrt0を用意したわけでもなかろうに。
どこの何見てそんなことやろうと思ったのか知らんが。
311 :
デフォルトの名無しさん :2008/02/14(木) 19:52:52
>>309 どうもです。retの後に(16ビットコードなのでmovw $1,%axみたいな感じ)
4行書いてみたんですが、相変わらずセグメンテーションフォルトでした。
32bitコードだと
----------ここから(label_32.s)----------
.globl main
main:
xorl %eax,%eax
movl %eax,%edx
movl %eax,%ebx
movl $0xFFFFFFFA,%eax
call ch_edx
movl $0xFFFFFFFB,%ebx
ret
ch_edx:
movl $0xFFFFFFFD,%edx
ret
----------ここまで----------
これでコンパイルすると正常に動作しました(gdbでstepiして確認)
>>310 crt0って何でしょう?すいませんよくわかりません。
コードはどこに載っていたというわけではなく
単に16bitコードをBSDで動かしてみたかったので。
URLか、何か適切な本があれば教えてくれませんか?
.code16が何か勘違いしている
313 :
デフォルトの名無しさん :2008/02/14(木) 20:08:36
it also supports writing code to run in real mode or in 16-bit protected mode code segments. To do this, put a `.code16' or `.code16gcc' directive before the assembly language instructions to be run in 16-bit mode.
315 :
309 :2008/02/14(木) 20:57:14
316 :
デフォルトの名無しさん :2008/02/14(木) 21:09:05
>>314 そこ読んでも何を勘違いしてるのかわかりません…
すいません教えてください。
BSDって16ビットコードを実行できたっけ?
リアルモードや16ビットプロテクトモード用の機械語を生成するように アセンブラに指示を出すのが.code16ディレクティブ。 *BSD系は普通32ビットプロテクトモードを使う。 32ビットモードで16ビットモードのコード食わせれば当然暴走することになる。
x86についての超初心者の質問ですが付き合ってください mov m,i; ってのは不可能なんでしょうか?つまり mov [esi], 0FFFFFFFFH; なんてのは無理なんでしょうか?
>>320 アセンブルできるよ。
念のため「うさみみハリケーン」付属の簡易アセンブラで試してみた。
mov dword ptr [esi], 0FFFFFFFFH
これをアセンブルすると、
C706FFFFFFFF
になった。
>>318 当然暴走するって言い方は乱暴だなぁ。
意味はないけど暴走しないように書く事だっでできる。
>>319 gdb使っているなら逆アセしてみれば、なぜ落ちるかわかるはず。
>>322 call ch_dxの手前まで進んでSIGSEGVを出して落ちたので
本来$eipが32bitで指し示しているアドレスを、.code16モードでは
その下位16bitしか読まないため、不正なアドレスにアクセスしようとして
エラーが出たんじゃないかと思います。たぶんですが
324 :
320 :2008/02/15(金) 05:47:09
>>321 ありがとうございます!
ptr演算子ってのがあるんですね。勉強になりました
それはMASM系の構文かな
>>323 はずれ。
ヒント
.code16のmovwと.code32のmovlは同じコード
328 :
デフォルトの名無しさん :2008/02/25(月) 15:25:47
329 :
デフォルトの名無しさん :2008/06/01(日) 12:34:51
スレが伸びない mov ah,4ch int 21h
halt
331 :
デフォルトの名無しさん :2008/06/02(月) 16:32:39
nop nop nop
CPUによっては、halt命令は相対ジャンプ命令だし、nop命令はレジスタ間演算命令だったりする罠。
9090909090909090
jump 1 (もう忘れたよ)
【データの交換】 N 番地と M 番地のデータを交換するプログラムを作成しなさい.
push [N] push [M] pop [N] pop [M]
>>336 それってレジスタNとレジスタMでの交換じぇねえか?
自信ないけど。
>335の問題はN番地とM番地の交換だろ?
普通は括弧ついてりゃメモリだろう。
レジスタ使わない(スタックポインタは使うけど元に戻る) push [N] push [M] pop [N] pop [M] レジスタ1個使う mov K, [N] xor K, [M] xor [M], K xor K, [M] mov [N], K レジスタ1個使う(スタックポインタも使うけど元に戻る) mov K, [N] push [M] pop [N] mov [M], K レジスタ2個使う mov K, [N] mov L, [M] mov [N], L mov [M], K レジスタ使用数と速度を比較してみると面白いか。
xchg [N], eax xchg [M], eax xchg [N], eax
xchg はつい忘れてしまうから困る
プロセッサを指定しないと駄目だろ・・・。
xchg eax,eax
全プロセッサでやればいいじゃん
lea ってどうやってアドレス計算しとんじゃボケ!
アセンブラって、今から勉強しても時代遅れ?
IA-64をハンドアセンブルできたら英雄になれる
EB08とかあったな。 単純JUMP8バイト。
351 :
デフォルトの名無しさん :2008/06/29(日) 14:09:28
アセンブリ言語を勉強しようと思い書籍を探しているのですが、 はじめて読むアセンブラ と いまどきのアセンブラの教科書 は持っているのですが、どうもわからないので、 とっつきやすい書籍を紹介してほしいです。
それはもう、本を読むよりも手を動かした方がいいということだ。
いや、さすがに教科書が宜しくない。 PIC か何か、PCではないもので学ぶか、PC で学ぶかという選択肢はあるが、 後者なら「はじめて読むPentiumマシン語入門編」をすすめておく。
あ、もしWindowsじゃない環境だったら... と書こうと思ったけど そのレベルなら自力でなんとかすると思うので続きは (省略されました)
355 :
デフォルトの名無しさん :2008/06/30(月) 09:42:15
とにかく手を動かして見る事にします。 お願いします。 僕に課題を下さい
アセンブラだけで全部書こうとか思ってるから厳しいんだと思うよ Windows上なら Delphiのインラインアセンブラとか手軽に利用出来て便利 多倍長の四則演算あたりを書いてみたらいいと思うな。
多倍長か…。 ハードウェアで乗算器の設計しようとして、1024bitの加算器を使おうとしたあふぉがいたなあ。 (某大手企業の中堅クラス以上の社員) シフト加算で何とかなるとか言っていた。w
358 :
デフォルトの名無しさん :2008/08/18(月) 16:54:10
DOSの時 OUT命令でFM音源動かしたり VRAMに直接書き込んだりしていたけど ウィンドウだと出来るのでしょうか 複雑すぎて自分ではやれないとは思うのですけどね
359 :
デフォルトの名無しさん :2008/08/18(月) 17:20:25
WindowsはOSですから。 そうですよねえ。 直接やりたいですよね。 んで、しつこいですけどもう一度。 WindowsはOSです。 わかりますよね??言ってる事。
saveDS dw ? saveES dw ? saveSS dw ? ;; void RealToProto(void); public _RealToProto _RealToProto proc near push bp mov bp,sp ; mov saveDS, ds mov saveES, es mov saveSS, ss これは、はじめて読む486という本にあるリアルモードのプログラムの一部なんですが、 saveDSをコードセグメント内で定義したら、mov saveDS, dsは mov CS:saveDS, dsと解釈されアセンブルされるのでしょうか?
call GetLocalTime movzx eax,word[SystemTimewHour] mov ebx,60 mul ebx movzx ebx,word[SystemTimewMinute] add eax,ebx mov ebx,60 mul ebx movzx ebx,word[SystemTimewSecond] add eax,ebx ret
>>358 ウィンドウってX?ms?
どっちでもやろうと思えばできる。
ただ、やらない方がいい。
bits 32 extern MessageBoxA section .data title: db 'title',0 string: db 'Hello World!',0 section .text global start start: push dword 0 push dword title push dword string push dword 0 call MessageBoxA ret
>>360 そんなお節介なアセンブラいらね。
ちう事で自分でオーバーライド。
365 :
デフォルトの名無しさん :2008/08/19(火) 17:13:58
>>362 やれなくはないのですね
>>359 リアルモードとプロテクトモードだと
メモリのアクセス方法とか全然違うんだよねっと
思っただけです
MS-DOSで動くのMASMのプログラムの中に flush_q2: db 0eah dw offset set_cs_desc3 dw seg set_cs_desc3 set_cs_desc3: って書いてあります。DOSから割り当てられるセグメントは 決まってないと思うのですが、dw seg set_cs_desc3 はどうしてアセンブルできるのでしょうか?
exeヘッダにリロケート情報が入っててメモリにロードしたときパッチが当たるんじゃなかったかな
>>358 何がどう複雑かって言うと、マルチタスクなので複数のプログラムが同時にIOしようとする
可能性を考慮しないといけないところ。だから、普通だとIOはデバイスドライバの仕事。
ドライバは複数のプログラムの要求を調停しながらIOを行う。
これが一般のアプリケーションには抽象化されたOSのAPIという形になる。
変わったところでは、16bitのと9xのWindowsがAPIだけでなくDOSシステムコールなども
そのままデバイスドライバへの要求に使えるというのがあった。DOS窓でDOSアプリケーションを
動かすための仕組みだが、副作用としてWindowsアプリケーションでもINとOUTなどができてしまう。
もちろん、そのIN/OUTはドライバが捕まえて、ドライバが代わりにやり直すんだけどな。
もう1つ、近頃はWindows用のドライバさえ用意すればよいという風潮で、
直接叩く方法が分からないハードウェアが多いというのも問題。
369 :
デフォルトの名無しさん :2008/08/20(水) 15:26:40
>>368 何か複雑ですね
out文をいろいろやったりするのが好きだったものです
370 :
デフォルトの名無しさん :2008/08/22(金) 02:22:51
こういうのは困難とは言わん。命令表みながらやれば小学生でもできる。 難読化もされてなけりゃ意地悪い箇所もない親切で読みやすいプログラムじゃないか。 面倒でも1命令づつ読んでいけ。この程度を読むのが嫌なら何もするな。
>>370 折角の課題なのに「勉強しよう」スレで勉強する気ゼロな依頼をするとはこれ如何。
Excelか・・ せんせいはきっと、 「分かり易く図や表を使ってね」 と暗に言ってるんだろう。そこを押さえればバッチグーだな m9(^Д^)
普通にエクセルの表にするだけだろ 図が要るとは思えないが
375 :
デフォルトの名無しさん :2008/08/23(土) 23:21:34
質問です。 x86のeaxなど汎用レジスタの上位16ビットと下位16ビットを 入れ替える命令ってありませんでしたっけ?
rol eax, 16
377 :
デフォルトの名無しさん :2008/08/23(土) 23:33:41
>>376 やっぱローテートでやるんですね。どうもありがとうございます
378 :
デフォルトの名無しさん :2008/08/27(水) 15:57:58
ローテートは遅い
バレルシフタが載って以降は普通にできるんじゃない?
xchg ah, al
それ16ビットレジスタの上位8ビットと下位8ビットだから
強引にxchgでやってみる。 xchg ah,al bswap eax xchg ah,al 普通に回した方が早いよなあ。
手元の資料じゃローテートはシフトと同じレイテンシ/スループットになってる。 ネットバーストでの記述だからレイテンシ4サイクルだけどPenM以降なら1に戻ってるだろうな。
004B4ADA . 81B8 98020000 >CMP DWORD PTR DS:[EAX+298],4349726F 004B4AE4 . 74 12 JE SHORT kuma.004B4AF8 EAXに入っている値+298のアドレスに入っている値とアドレス4349726Fの比較ですか?
違う
TEST BYTE PTR SS:[ESP+8],1 MOV DWORD PTR DS:[ESI+4],0 MOV DWORD PTR DS:[ESI+8],0 MOV DWORD PTR DS:[ESI+C],0 JE SHORT ESP+8のアドレスの中身と1の論理積を取る 定数0を入れる ZF = 1 ならジャンプ これであってますでしょうか?
何の石かちゃんと書いてくれ。 書いてないものは68K/Coldfireとみなすからな。
68KにDS:なんてないだろ。
ないな。で?
>>386 プロテクトモードか?
そのmovでフラグは変化しないからあってる。
と思う。
バイトでアセンブラやるんだけど、アセンブラて何
機械語とほぼ1対1に対応するプログラミング言語の処理系
メインの組立ラインの横で部品を組み立てる仕事かもしれん
まさしくハンドアセンブラ?
837C24 04 E0 : CMP DWORD PTR SS:[ESP+4],-20 この場合10進数で-20、-52、-32のどれでしょうか? あと、-20という定数はここだけでしか使われていなかったのですが こういう定数は主にどのようなケースで使われるのでしょうか?
>>396 何の石の何のアセンブラかを書かないとわからない。
>>396 224だか-32だか。少なくとも、-52なんてことは有り得ない。
コードがE0になってるからここでは-32が正解 一般的には16進の定数は 20h 0x20 $20 などの表記をすることが多い。
400 :
396 :2008/09/24(水) 07:59:05
402 :
デフォルトの名無しさん :2008/11/03(月) 19:30:27
8個のスイッチからデータを入力し、そのデータが55Hとなった時に LEDすべて点滅するプログラムを作るにはどうしたら良いか? 解き方がわかりません!どなたか解き方を教えて下さい! また、上と同様に、スイッチのデータが10Hより大きい時 LEDのビット7が点滅し、スイッチのデータがOFHより 小さい時はLEDのビット0が点滅するプログラムを作る には、どうしたら良いか? こちらもお願いします!
コピペ君って馬鹿だな、まで読んだ。
排他的論理和とゼロフラグだな。 下は教える気にもならんほど初級
>>402 書いてやってもよいが、せめて石と言語くらい書いてくれ。
406 :
デフォルトの名無しさん :2008/11/04(火) 18:51:09
>>405 ぜひ、助けて下さい。 ↓ のような感じで、プログラムお願いします。
10 ORG 0100H
20PA EQU 20H ちなみに、アセンブラ言語・8255です。
30CR EQU 23H
40 LD A,98H
8255はパラレルインターフェースなのだが。 だいたい、どうやってスイッチを読むのか、どうやってLEDの制御をするのかを 指定してくれなければ何もガイドできないぞ。
初心者だからわかりません!そのくらいさっしてください!
昔、BASICのエディタを利用して入力するアセンブラ(行番号を無視する)とか あったけど、そういうのかなぁ?
411 :
デフォルトの名無しさん :2008/11/04(火) 19:39:26
まあ、順調にレポート落としてくれや 誰かが手助けできる程度の情報を提供できるようになってからまた来なさい
ORG 0000 LXI SP,0A000H ; RAMの末尾番地 JMP MAIN SW EQU 0E000H ; SWのMAPされる番地 LED EQU 0F000H ; LEDのMAPされる番地 ORG 0100h ; 飛ばした場所には割り込みベクタが置かれる 朝飯だから続きは後で
MAIN: LDA SW
CMA ; 8bitパラレル入力は8255にDIPSW入力を仮定。負論理のことが多いのでここで反転
CPI 055H
JZ ALLBLINK
CPI 010H
JC UNDER ; 10Hを引いてキャリー=0F以下。
>>402 では10より大、0Fより小と言って
; いるが、10/0Fと等しいときの処理が読みとれないので10以上と未満と解釈する。
LOOP1: ; ここが10H以上のとき。
MVI A,0FFH
STA LED ; LEDにFF(All Off)をライト
CALL DELAY ; 後で作る。たぶん1秒ぐらい
MVI A,000H
STA LED ; LEDに00(All On)をライト
CALL DELAY
JMP LOOP1
ごめん、上のはALLBLINKの処理だ。 LOOP1: ; ここが10H以上のとき。 MVI A,80H STA LED ; LEDに80H(bit7off)をライト CALL DELAY ; 後で作る。たぶん1秒ぐらい MVI A,000H STA LED ; LEDに00(bit7 On)をライト CALL DELAY JMP LOOP1 ALLBLINK: ; ここが55Hと一致したとき。 MVI A,0FFH STA LED ; LEDにFF(All Off)をライト CALL DELAY ; 後で作る。たぶん1秒ぐらい MVI A,000H STA LED ; LEDに00(All On)をライト CALL DELAY JMP ALLBLINK
UNDER: ; ここが0FH以下(=10H未満)のとき MVI A,01H STA LED ; LEDに01(bit0 off)をライト CALL DELAY ; 後で作る。たぶん1秒ぐらい MVI A,0FEH STA LED ; LEDにFE(bit0 ON)をライト CALL DELAY JMP UNDER DELAY: ; clockが書かれてないので、とりあえず俺のやってる3.072MHzで LXI B,8 DELAY0: LXI H,0 DELAY1: DCX H MOV A,L ORA H JNZ DELAY1 ; 内側のloopが6clock*65536回回る。 DCX B MOV A,C ORA B JNZ DELAY0 ; 外側のloop8回で1秒ぐらい。 RET
>>415 の、LOOP1の所、bit7 offのパターンは LDA 0FFH (他のbitはoff)
bit7 ONのパターンは LDA 07FH (他のbitはoff) の間違いでした。
本当は8253とかの外付けタイマをRST7.5に割り込み入れてソフトタイマを減算したほうが
スマートなのだけど、402はそういう余計な情報を消化できないと思って、loopでディレイを
作りました。割り込みを使う方法も知りたければその旨書いてね。
ザイログニモニックでないとピンとこない・・・
なんという・・・書いてやってもいいけど、自分で翻訳できるでしょ。MOVがLD、ORAはOR A, とか もうすぐ朝飯だから、気が向いたら午後にでも書きにくるかも。
宿題の人がザイログニモニックという単語を知ってるとは思えないが
宿題の人のためじゃないけど、暇なので書いてみた。 ORG 0000 LD SP,0A000H ; RAMの末尾番地 JP MAIN SW EQU 0E000H ; SWのMAPされる番地 LED EQU 0F000H ; LEDのMAPされる番地 ORG 0100h ; 飛ばした場所には割り込みベクタが置かれる 16進4桁のportアドレスだと、たしかIN/OUTは A,(BC)とかを使うんだよね。 この先書いてる間に誰かフォローお願い。
MAIN: LD BC,SW
IN A,(BC)
XXX ; Aregの反転。負論理のことが多いのでここで反転
CP 055H
JP Z,ALLBLINK
CP 010H
JP C,UNDER ; 10Hを引いてキャリー=0F以下。
>>402 では10より大、0Fより小と言って
; いるが、10/0Fと等しいときの処理が読みとれないので10以上と未満と解釈する。
LOOP1: ; ここが10H以上のとき。
LD A,0FFH
LD BC,LED
OUT (BC),A ; LEDにFF(All Off)をライト
CALL DELAY ; 後で作る。たぶん1秒ぐらい
LD A,0
LD BC,LED
OUT (BC),A ; LEDに00(All On)をライト
CALL DELAY
JP LOOP1
コンプリメントのニーモニックが判らなくてゴメン。読む人はザイログ慣れてるでしょうから補って。
ごめん、上のはALLBLINKの処理だ。 LOOP1: ; ここが10H以上のとき。 LD A,0FFH LD BC,LED OUT (BC),A ; LEDにFF(bit7 Off)をライト CALL DELAY ; 後で作る。たぶん1秒ぐらい MVI A,07FH LD BC,LED OUT (BC),A ; LEDに7F(bit7 On)をライト CALL DELAY JMP LOOP1 ALLBLINK: ; ここが55Hと一致したとき。 LD A,0FFH LD BC,LED OUT (BC),A ; LEDにFF(All Off)をライト CALL DELAY ; 後で作る。たぶん1秒ぐらい LD A,000H LD BC,LED OUT (BC),A ; LEDに00(All On)をライト CALL DELAY JP ALLBLINK
UNDER: ; ここが0FH以下(=10H未満)のとき LD A,255 LD BC,LED OUT (BC),A ; LEDにFF(bit0 Off)をライト CALL DELAY ; 後で作る。たぶん1秒ぐらい LD A,0FEH LD BC,LED OUT (BC),A ; LEDにFE(bit0 On)をライト CALL DELAY JMP UNDER DELAY: ; clockが書かれてないので、とりあえず俺のやってる3.072MHzで LD BC,8 DELAY0: LD HL,0 DELAY1: DEC HL LD A,L OR A,H JP NZ,DELAY1 ; 内側のloopが6clock*65536回回る。 DEC BC LD A,C OR A,B JP NZ,DELAY0 ; 外側のloop8回で1秒ぐらい。 RET
こんなのでよかったかな。今からアセンブルしてみる(先にやってから書けよw) Z80も今では作られてないだろうから、実際に動かすならZ80180か川崎の180かな。 バンクとか、幾つかの内蔵I/Oレジスタの初期化が要るはずだが、デフォが16bitリニアな アドレス空間になっていると思うので、デフォのままで動くのでしょう。
いっぱい書きミスがありました(w アセンブルリスト貼ると、' 'が詰まるんだろうな。
CSEG
ORG 0000
0000 3100A0 LD SP,0A000H ; RAMの末尾番地
0003 C30001 JP MAIN
E000= SW EQU 0E000H ; SWのMAPされる番地
F000= LED EQU 0F000H ; LEDのMAPされる番地
ORG 0100h ; 飛ばした場所には割り込みベクタが置かれる
0100 0100E0 MAIN: LD BC,SW
0103 ED78 IN A,(C)
0105 1EFF LD E,255
0107 AB XOR E ; Aregの反転。負論理のことが多いのでここで反転
0108 FE55 CP 055H
010A CA2901 JP Z,ALLBLINK
010D FE10 CP 010H
010F DA4001 JP C,UNDER ; 10Hを引いてキャリー=0F以下。
>>402 では10より大、0Fより小と言って
; いるが、10/0Fと等しいときの処理が読みとれないので10以上と未満と解釈する。
0112 LOOP1: ; ここが10H以上のとき。 0112 3EFF LD A,0FFH 0114 0100F0 LD BC,LED 0117 ED79 OUT (C),A ; LEDにFF(bit7 Off)をライト 0119 CD5701 CALL DELAY ; 後で作る。たぶん1秒ぐらい 011C 3E7F LD A,07FH 011E 0100F0 LD BC,LED 0121 ED79 OUT (C),A ; LEDに7F(bit7 On)をライト 0123 CD5701 CALL DELAY 0126 C31201 JP LOOP1 0129 ALLBLINK: ; ここが55Hと一致したとき。 0129 3EFF LD A,0FFH 012B 0100F0 LD BC,LED 012E ED79 OUT (C),A ; LEDにFF(All Off)をライト 0130 CD5701 CALL DELAY ; 後で作る。たぶん1秒ぐらい 0133 3E00 LD A,000H 0135 0100F0 LD BC,LED 0138 ED79 OUT (C),A ; LEDに00(All On)をライト 013A CD5701 CALL DELAY 013D C32901 JP ALLBLINK
0140 UNDER: ; ここが0FH以下(=10H未満)のとき 0140 3EFF LD A,255 0142 0100F0 LD BC,LED 0145 ED79 OUT (C),A ; LEDにFF(bit0 Off)をライト 0147 CD5701 CALL DELAY ; 後で作る。たぶん1秒ぐらい 014A 3EFE LD A,0FEH 014C 0100F0 LD BC,LED 014F ED79 OUT (C),A ; LEDにFE(bit0 On)をライト 0151 CD5701 CALL DELAY 0154 C34001 JP UNDER 0157 DELAY: ; clockが書かれてないので、とりあえず俺のやってる3.072MHzで 0157 010800 LD BC,8 015A DELAY0: 015A 210000 LD HL,0 015D DELAY1: 015D 2B DEC HL 015E 7D LD A,L 015F B4 OR H 0160 C25D01 JP NZ,DELAY1 ; 内側のloopが6clock*65536回回る。 0163 0B DEC BC 0164 79 LD A,C 0165 B0 OR B 0166 C25A01 JP NZ,DELAY0 ; 外側のloop8回で1秒ぐらい。 0169 C9 RET 016A END ここからcopyしてスペースの所をタブに変えれば読めるリストに戻ります。
Z80の可能なニーモニックを片っ端から書いてRZ80してみてるんですが、EX AF,AF' って書いて *** missing quote syntax error ってエラーが出るんですよ。これどう書けばいいんだろ・・・
ハンドアセンブルしてDBで書く
432 :
429 :2008/11/10(月) 04:56:57
EX AF,AF でエラー消えました。メッセージの意味が反対ですよね。 IN r,(C) とか、OUT (C),r って、A以外の諸レジスタもrに(文法上は)書けるのですが、 BやCを使うことはないし、D〜Lだってまず使わないですよね。なんでこんなこと許してるのかな。
inrやoutrのため。それと、(c)と言いつつ実はアドレスバスにはbcが乗るので、 I/Oポートアドレス空間を64KiBフルにデコードすることも可能といえば可能。 それを利用したのがSonyのHitBitじゃなかったかな。
>>432 ’〜で後ろの"'"が無いことになってるんだから別に間違ってなかろう。
EX AF,AF'だけ特別扱いするのはめんどいし。
rでA以外も受け付けるのは、その方が簡単だから。
435 :
429 :2008/11/11(火) 05:01:14
>>433 INIRやOTIRのことですね? 連続したポートアドレスから幾つも読み書きするって
実機でそういう構成の奴はやったことないんですよね。どなたかありますか?
>>434 missing〜って、quoteがありませんよ、という文句だと思ってました。あるのに・・・
Z80のほぼ全ての命令を書いてASMリストを取り、コードの頭でsortして>z80.dicに出して、
同様に作った8085.dicと見比べると、面白いですね。8080の命令は実行できるように作られた
そうですが、けっこう違う所がありました。
8085 Z80
コード0F,1F RRC,RAR 無い RRC a、RR a で同機能の拡張命令がある
コード2F CMA 無い
コード30 SIM JR NC,xx
コード3F CMC 無い
コードC0 RNZ 無い
コードC4 CNZ 無い
コードC8 RZ 無い
コードCC CZ 無い
コードCB 無い bit操作命令の開始バイト
コードCF RST 1 無い
コードD0 RNC 無い
コードD4 CNC 無い
コードD8 RC 無い
コードDC CC 無い
コードDD 無い IXレジスタ操作命令の1バイト目
コードDF RST 3 無い
コードE0 RPO 無い
コードE2 JPO 無い
コードE4 CPO 無い
コードE7 RST 4 無い
8085にあってz80にないのは二つだけ。RRCはz80拡張命令とではフラグの動きが違う。
>>435 普通は「'hoge'」と書かなきゃいかんのに「AF'」て書いたんで、
「'」が閉じてないがなといわれてるんですな。
IN[ID]R/OT[ID]RはCの値変わんないので、同じ所をどかどか読み書きするんですな。
で、OTIRはZ80DMAとかZ80SIOの初期化に使ってた記憶が。
あのへんは無駄に初期設定大変だったからなあ…
なんて事を書いていたらZ80ファミリハンドブック読みたくなってきた。
どこにしまったかのう。
私の机の上にあるよ。
439 :
429 :2008/11/11(火) 11:03:31
>>436 435で書いた諸々の無い命令は、どんな書式になりますか?
RST 1〜7はoperand errorになりました。return on condition とか call on condition とかも
書式が判りません。 今はコード照合しながら書いてない命令が無いかチェックしてます。
441 :
429 :2008/11/11(火) 12:54:43
あ〜、これはいいものをありがとうございます。メモメモ・・・ RSTは番号じゃなくてマスクを書くんですね。
442 :
429 :2008/11/12(水) 03:23:04
全部の命令コードをアセンブルできました。
>>436 の2つってどれのことですか?
>>442 rim, sim。それらのコードはz80では全く違うインストラクションに割り当てられている。
8085では8080にこのインストラクションを追加した仕様になっている。
面白いところでは、8085にもz80にもドキュメントされていない隠しニモニックが多数ある。
その辺りは、ますます8085とz80の互換性がなくなる結果になっている。
444 :
429 :2008/11/12(水) 04:38:39
あ、ホントだ。JRとJR NC ですね。NR80ではrimとsimはDBで書いてました。 割り込みマスクのread/writeなんてごく一部のコードしか使わないから、 アプリ層だったら85のコードをZ80で実行するのはありですね。 でも実際には周辺ICも違うから、なかなかそういう場面はなさそう。
現在8085の課題をやっているのですが 他の課題に負われ8085の方の内容がまったくつかめないままここまで来てしまいました 八方塞の状態でまったく出来ません(独自でやっていたのですがとてもでは無いですができそうではないです) とりあえず形になっていればいいのですが、提出が明日の午前11時が期限になっています もしよければ協力してくれる方いらっしゃいませんか(当方、かなり必死です…) 課題の内容 8085でデジタル目覚まし時計の作成をせよ ・タイマ割り込みは必須 ・設定した時間で音がなる ・複数のスイッチを入力する事で音が止まるようにする 以上の条件を満たす、フローチャートを作成し、プログラムを作成せよ
>>445 > 8085でデジタル目覚まし時計の作成をせよ
> ・タイマ割り込みは必須
> ・設定した時間で音がなる
> ・複数のスイッチを入力する事で音が止まるようにする
回路図とかあるんかい?
>>446 無いです
フローチャートを作成して
それに乗っ取ったプログラミングをすることが課題となっています
>>446 うんじゃ、以下の質問に答えれ
o タイマり込みって何をどう叩いて割り込ませるの?
o 音って何をどう叩いて出てくるの?
o スイッチってどこを読めば ON/OFF 判定できるの?
449 :
445 :2008/11/12(水) 22:20:05
>>448 ちょっと待っていてください
全部答えられるかわかりませんが
参考になるだろうプログラムがあるのでちょっとアップしてみます
450 :
445 :2008/11/12(水) 22:43:22
451 :
デフォルトの名無しさん :2008/11/13(木) 02:42:33
さっき起きたが、もう流れてる。とりあえず、手持ちのASMから使えそうなとこ拾ってあげる。 ファイルabs.asm=cのmainに飛ばすための初期化コードから: CSEG ORG 0000h LXI SP,0A000h ; RAMの末尾番地 JMP MAIN ; cのmainに飛ばすにはc_main_ ORG 003Ch ; RST7.5の割り込みベクタの番地 JMP TIMER ; 8253という石をつなぎ、ここに割り込みを入れるよう設定する
P53_0 EQU 0F000h ; 8253がMAPされるアドレス空間 P53_1 EQU 0F001h P53_2 EQU 0F002h P53_3 EQU 0F003h MAIN: ; main loopの開始 /* 8253初期化 */ P53_3 = 0x36; /* カウンタ0 Bin, mode3, ライトLSB,MSB */ P53_3 = 0x76; /* カウンタ1 Bin, mode3, ライトLSB,MSB */ P53_3 = 0xB6; /* カウンタ2 Bin, mode3, ライトLSB,MSB */ /* mode3だと方形波が出るだけなので、カウンタ2はmode0にして割込み を使う方が正論だが、カウンタ2出力先の8085のRST7.5がエッジトリガ- なのでmode3(方形波)でうまく行く。CPUによってはmode0を 使わなければならないが、その時は割込み処理でカウンタ2をリロード しなければならない。 */ P53_2 = 30720 & 0xFF; /* カウンタ 2 LSB */ P53_2 = 30720 >> 8; /* カウンタ 2 MSB */ /* 3.072MHz/30720 = 100Hz ( 10mS毎 ) */ RST7.5割り込みを使う理由はコメントを読んでね。このcコードと同じ意味のASMは書ける?
453 :
455 :2008/11/13(木) 02:52:13
メインループの概要:
>>452 のように8253を初期化
時刻メモリを00:00:00に設定
loop:
SWを読む
SWの時刻とメモリが一致したら音を鳴らす/または止める
loopへJMP
455 :
455 :2008/11/13(木) 02:58:44
>>452 >このcコードと同じ意味のASMは書ける?
ちょっと辛いと思います・・・orz
456 :
455 :2008/11/13(木) 03:00:27
>>454 ああ、非常にわかりやすいです
ありがとうございます
ざっと読んだ。ORGのアドレスとかは
>>453 の環境のように直せるよね?
CSEGは、リンカで再配置するための命令で、ASEGはASMが吐いたオブジェクトをそのまま
実行アドレスにするためなのは理解してる?
今回は音は単なる断続音でいいと思うから、MUSICのテーブルMUSIC:の所を、
音・休符のくり返しにしておけばいい。
>>455 しょ〜がねーなあ・・・
P53_3 = 0x36; /* カウンタ0 Bin, mode3, ライトLSB,MSB */
MVI A,036h
STA P53_3
P53_3 = 0x76; /* カウンタ1 Bin, mode3, ライトLSB,MSB */
MVI A,076h
STA P53_3
P53_3 = 0xB6; /* カウンタ2 Bin, mode3, ライトLSB,MSB */
MVI A,0B6h
STA P53_3
P53_2 = 30720 & 0xFF; /* カウンタ 2 LSB */
MVI A,0FFh
STA P53_2
P53_2 = 30720 >> 8; /* カウンタ 2 MSB */
MVI A,30720/256
STA P53_2
>>457 >ORGのアドレスとかは
>>453 の環境のように直せるよね?
試行錯誤してみますが即時にはちょっと辛いかもしれません
>>458 あまりの優しさに。・゚・(ノД`)・゚・。
cのコメントを; にしてASMに振ってね。 なかなか本題に入れないな(w TIMER: ; 8253をつないで上のように初期化すると、10mSごとに割り込みが発生し、ここにジャンプしてくる ; 8253は___|~~~|___|~~~|___|~~~・・・という信号を出し、これの立ち下がりエッジを8085は割り込みと認識する訳。 PUSH H PUSH D PUSH B PUSH PSW (割り込み処理本体) POP PSW POP B POP D POP H ; メインで使っているレジスタをこういうpush/popで保護する。順序は判るよね? EI ; 割り込んだときいったんDI状態になるのでそれを回復(また割り込み可能に) RET ; 割り込んだ次の番地(メインのどこか)に復帰 こういうのが割り込み処理プログラミングの基本的なお作法です。
461 :
445 :2008/11/13(木) 03:22:32
俺の環境は、プログラムのコード(実行命令部)はROMの0番地から、RAMは0A000番地〜
数`バイト、という物なのでORG 0000hになってるわけ。
>>455 の環境はASMの吐いたコードを
RAMにロードして実行させる環境なのではないかと思う。ORG 8000hとか書かれてるから。
463 :
445 :2008/11/13(木) 03:28:02
>>462 >RAMにロードして実行させる環境なのではないかと思う
はい、その通りです
割り込み処理本体:
TIMER1: DS 1 ; soft couter 1 100回をカウントし、1秒を作る
SEC: DS 1 ; 秒カウンタ
MIN: DS 1 ; 分カウンタ
HOUR: DS ; 時カウンタ
変数としては最低限、この位は必要だね。
CSEGは上でも書いたけどROMにロードさせるためのアセンブラ命令なので、
>>455 はASEGで書き始めればいい。
465 :
445 :2008/11/13(木) 03:42:01
割り込み処理本体の実行部: TIMER1を減算、0になったらまた100を入れる。(MAINの初期化時に100にしておくべき) 0になったときが「1秒ごと」だから、その時に 秒を加算、59を越えたら、0に戻し、 分を加算、59を越えたら、0に戻し、 時を加算、23を越えたら、0に戻す(日付までやるとえらいことになるぞ。) 時分秒を(表示器があれば)表示器に表示。 (これは割り込み中にやらずに、メインループに対しフラグで通知して、メインループで 表示してもらう手法が一般的だ。こういう情報(割り込みからメインループに伝える情報) が「イベント」という概念で教えられているものだ。 時刻そのものではなく、「表示が必要だよ」という情報ね。 割り込み処理では時刻を変更する、メインではそれを読みとるのみで変更はしない。) 音が鳴っている状態であれば、音用のポートのON/OFFを切り換える (これで、警報音の断続が制御できる) 段付け毎にcのif文=ASMならCPI 、JCかJZかJNZで分岐が必要なのは判るよね。 時分秒は00:00:00〜23:59:59だから、SW入力は8bitのDIPSWか何かが3器つながる必要がある。 その辺は455の環境に合わせてI/Oの番地を書いてね。 プログラムの基本構成はこれで伝わったとおもう。全部書いてあげるのじゃカンニングみたいだし、 そろそろ朝飯食って出勤なので、ここまでにしたい。
思い出した。毎年今頃に8085の質問投げてくるkitの学生か?
468 :
445 :2008/11/13(木) 03:56:42
>>466 お疲れ様でした
大変、助かりました
これを元に頑張ってみます
本当にありがとうございました
469 :
445 :2008/11/13(木) 03:58:14
>>467 kitは大当たりですw
前例いたんですねw
工芸繊維大!?
どこだ?九州工業大学か?
472 :
467 :2008/11/15(土) 04:20:18
上の方で誰かがkitって書いてたんだが、俺もkitが何なのか知りたいな。
473 :
467 :2008/11/15(土) 04:34:12
あ(*o*) Kyuusyuu Institute of Technology か
金馬鹿工業大学
Knight Industries Two Thousand
お邪魔します。基本情報処理試験(午後 アセンブラ)の問題集を解いているのですが 解らない問題で行き詰りました。 こちらで教えて頂ますでしょうか? スレ違いでしたら申し訳ございません。(CASLU 福嶋宏訓 著)
477 :
467 :2008/11/19(水) 17:54:40
スレチじゃないけど、俺は85得意だがCASL音痴なんでお役に立てない(m_ _m)
ダウンロードしたzipを強制解凍してくと〜〜ml_exe〜〜というファイルが出てくる。 これがml.exe本体だから適宜リネーム。
480 :
478 :2008/11/23(日) 07:23:50
ありがとうございます。 しかし、なぜこんな面倒なことせにゃならんのでしょうかね。 MSはアホなのでしょうか。
つーか、VC++2008EEならそんな面倒なコトしなくてもSP1あてれば ml ver9が勝手に入んないか?
482 :
478 :2008/11/23(日) 08:51:08
with SP1なるものが出ていたんですね。今から入れ直します。どうもです。
483 :
デフォルトの名無しさん :2008/11/23(日) 18:04:37
c言語のscanfと同じようなことをアセンブラで実行したいんですけど どういうプログラムを書いたらいいか分かりません どなたかヒントください
Cのscanfをアセンブラから呼べばいい。
アセンブラって、書くのは労力いりそうですが、習得するのは簡単 ですよね?C言語とかよりも。
プロセッサによる。IA64のアセンブラは死ぬるぞよ。
x86は?
>>483 「可変個の引数リスト」 を扱うってとこがミソかな。
引数リストの場所を覚えておくポインタを設ければいい。cではそのような書き方をしてるはず。
インラインアセンブラを使う場合に _asm{}と__asm{}と2種類を見かけたのですが、どう違うのでしょうか。
>>488 IA64よりは簡単。VLIWのアセンブラは人間が書くものじゃねえ。
まあ32bitでRing3だけなら簡単な方じゃないかと思う。
>>490 書き方。
IA-64はバンドルに無理やり詰め込まなければ難しくない。
IA-64というかItaniumって、けっきょく商業的には失敗作なんでしょ? 消えゆく運命か?
HPC用途でもうしばらくは・・・ まあ、そもそもアセンブラでガリガリ書くようなプロセッサじゃないし
とりあえず漠然とアセンブリを学習する場合は、16ビットプログラミングが 初心者にはいいの? 32ビットでも変わらない?
実行環境を確保できるものにしとけ。
MS-DOS はアセンブリ言語勉強するのにいい環境だったな・・・。 割り込みとか簡単にできたし。
16ビットっていうと今では無用なセグメント方式とか思い出すな
499 :
デフォルトの名無しさん :2008/11/26(水) 18:26:22
Linuxとかだとアドレッシングにセグメント機能通してるし、方式自体は生きてるけどなあ・・ でもいつまで残るんだろね。 Intelがそれを望む限り続くんだろうけどさ。
Linuxってどこでセグメントレジスタ活用しているの? 4GBフラットアドレスに設定しているだけだと思うのだが。
>>500 >4GBフラットアドレスに設定しているだけだと思うのだが。
え?そこで使ってるじゃんセグメントレジスタ。
だったらWindowsもそだね
Win2Kまで使えたOS/2 1.x 互換モードが何気に変態ぽくて好きだったな。
フラットに使うだけだと「活用」してるとは言えないな。 32ビットCPUでメモリ空間を拡張するカーネルオプションとか あったような気もするけど...
>>501 それいったら、どうやってセグメントレジスタ抜きでx86を使うの。
64ビットモードならセグメントレジスタ無視が基本だから、使っていないと言えるだろうけど。
そういえば、x86-64はAMD発だから、
Intelはセグメントレジスタ潰したいのだろうと言う根拠に使うのは苦しいな。
x86版のWindowsは構造化例外処理にセグメントを思いっきり使っているが
いつの間にか追加され忘れ去られてしまったFSとGSのこと、時々でいいから思い出してください。
FSは例外で使われてるね
FSとGSはほんとに気が付いたらあった感じだね 386以降だっけか
Windowsのカーネルで使用するKPCR構造体はx86ではFS、x64ではGSを使ってアクセスしているよ。
GSって自由に使ってもいいの?
何をしたいのか環境によるっしょ
486から後のセグメントの意味と、386から前のセグメントの意味を混同している奴は恥ずかしいぞ。
すまん386と486の間のセグメントの違いはわからん。 リアルモードとプロテクトモードの違いのことじゃないよね?
それって、386以降のプロテクトモードでのメモリー空間マッピング機能とか領域保護機能のためのレジスタになったってやつ?
513は恥ずかしい奴。
513は386と286と言いたかったのだと思われ。 リアルモードとプロテクトモードと言い換えてもいいか。
286にも16bitプロテクトモードなんていうものがあって、186と286の間ではないかと。
GS, FSセグメントレジスタの使用、アドレッシングを目的を除く32Bitレジスタの使用は、 386以降ならリアルモードでも仮想86でも可能。 もちろんこのモードでのセグメントレジスタは伝統的な4ビットシフト型となる。
リアルモードに戻った直後のセグメントレジスタ更新前なら プロテクトモード時に設定されたアドレスにアクセス可能
4Gリアルモードとか呼ばれてる奴ですな
いい加減、モード大杉
今でもSSとCSを別にしているOSがあると聞いたことがある。セキュリティ上の理由で。 詳細は知らんが。
Windowsがアプリケーションのメモリ空間の拡張にAWEなんてやっていたけど、 そんなことするくらいならセレクタ復活させたらいいのにと思っていた。
>>523 Windowsのカーネルモード時のセグメントセレクタの基本値
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
CS!=SSですね。
>>524 それじゃAWEのかわりにならんだろ。
>>525 セレクタが違ってもディスクプリタが同じ領域をポイントしてる可能性もあるのでは。
>>523 Linuxとかそこらへん向けにそういう実装があったな、名前忘れたが。
4G全域でなく、必要な部分だけにきっちりセグメント範囲を限定することで
想定外のアクセスでフォルト起こすようにするんだったか。
互換を言うならx64のロングモードに仮想86を復活汁
>>525 >>526 手元にあるW2kのkernelModeだと、同じ場所を示していた。
CS:0008 SS:0010 DS:0023 ES:0023 FS:0030 GS:0000
GDT base:80036000 limit:03ff
0: 00 00 00 00 00 00 00 00
1: 00 cf 9b 00 00 00 ff ff
2: 00 cf 93 00 00 00 ff ff
3: 00 cf fb 00 00 00 ff ff
4: 00 cf f3 00 00 00 ff ff
5: 80 00 8b 2c 10 00 20 ab
6: ff c0 93 df f0 00 00 01
どうでも良い事だけどね。
アセンブリの入門書を2冊持っているのですが、どちらも実数定数に ついては、簡略・割愛しているのですが、実数定数は初心者には 複雑なのでしょうか? 実数の計算できないとお話にならない気もしますが…
複雑です 浮動小数点が必要な場面でアセンブラを使うような人なら そのあたりの情報はだいたい見つけられます
>>531 何のアセンブラかにも拠るからねぇ。定数ロードのインストラクションを持つチップもあることだし、大した話じゃないけどね。
>>532 それは、フォーマットが複雑だといっているのか?
>>533 入門書を読んでる人にとっちゃ、いろんな意味で複雑でしょ
一通り分かった人ならともかく
アセンブラ使いが実数? 何を頓珍漢な事言ってるんだ?? 実数演算が必要な所では計算式も煩雑だろうに 素直に高級言語使ってろって話だと思うがな。
例えばこんなコードなら複雑でもなんでもないじゃん。
# 実在するかは兎も角
invPi: ld rf0, #1.0
ldpi rf1
div rf0, rf1
ret
>>535 そうは言うがな大佐、読める能力はあるに越したことはないと思うぞ。
例えば、100.0を掛ける場合、この値をどう書くかとか、そういう辺りだろうね。
アセンブラが実数をサポートしていないなら諦める。
CPUやアセンブラを限定しないと答えようが無いうえ、定数が何を指してるかもあいまいかな。 1.実数計算機能が無いCPU 2.実数計算機能があり、直値のロードができないCPU 3.実数計算機能があり、直値のロードが可能なCPU と分けるとx86系は2になるので、x86で定数は静的なデータとして定義する必要がある。 .DATA hoge REAL8 10.12345 .CODE FLD hoge FLDPI ; 円周率の定数ロードは専用命令があったりする。
x86 の実数計算は、浮動小数点レジスタの扱いがすげー面倒なので覚えてないわ・・・。 SSEx 使った方が楽なんじゃないか。
>>539 ボクの486SXマシンじゃ実行出来ません ><
>>541 Win9xやNTのWin32アプリならx87のエミュレーションやってくれる。
>>540 XMMをスカラで使うと何か損した気分になる。
MS-DOSでアセンブラするには16ビット版リンカってのが必ずいるの?
いるよ〜。 アセンブラはVS2008についてくるWin32用のでいけるけどね。
どうもです。 lnk563.exeなるものを調達してきて、その中からlink.exeを取り出しました。 試しに実行ファイルを作ってみようと、ml ver9とそのlink.exeをasmファイルの あるディレクトリにぶちこんで ml /omf ???.asm と打ち込んだら、アセンブルは完了したのにリンカが自動呼び出しさせません。 なぜでしょうか。
>>545 >リンカが自動呼び出しさせません
って、実行のことか?
32bit用と16bit用でLinkの引数の書式が違うから、呼び出す前に互換があるか確認してるのかも。
/omf オプション自体が /cと同じでlinkerの呼び出しを行わなくする作用がある。
549 :
545 :2008/11/29(土) 13:10:02
確かに、32ビットリンカだと、mlコマンド打てば自動で呼び出されますね。 ただし、OMF形式でなくて、COFF形式でオブジェクトファイルを作成する 必要がありますが…。 16ビットの場合はOMF形式じゃないとだめらしいのですが、それで作っても リンカは呼び出されません。自前で全部引数入れなきゃだめですかね。
ダメです。ちゃんとmakefileを作るか諦めてバッチでどうぞ。
551 :
545 :2008/11/30(日) 00:52:02
そうですか、どうもです。
突然ですが、レガシーなDMAコントローラを使う場合、 CPUのキャッシュとDMAによる物理メモリへの書き込みとを同期させる には、far jmp 命令を実行すれば良かったんでしょうか?
x86でのDMA転送は、I/O Agent が勝手にsnoopして、物理メモリとキャッシュ と同期する、という噂がありますが、正式な資料がどこかにありませんかね。 IA-32 Intel Architecture Software Developer's Manualの Volume 3「System Programming Guide」 の 9.3.2節の以下の 部分に何となく書かれていますが、「できる(can performe)」ことと 「実際にそうなっている」事とは別ですから。 9.3.2. Choosing a Memory Type The simplest system memory model does not use memory-mapped I/O with read or write side effects, does not include a frame buffer, and uses the write-back memory type for all memory. An I/O agent can perform direct memory access (DMA) to write-back memory and the cache protocol maintains cache coherency.
554 :
a :2008/12/02(火) 15:06:54
age
>>552 far jmpはパイプラインが捨てられるだけだ。
キャッシュきれいにしたけりゃwbinvdあたり使わねば。
>>556 自己書き換えコードの直後に jmp するというのはキャッシュ・クリア
ではなくパイプライン・クリアでしたっけ?
言われてみれば、データ用のキャッシュは、CPU自身の書き換えでは
整合するに決まってますね。
>>555 PCIは、あるデバイスがマスターになって、メモリに転送する機能が
定められている。Legacy DMAは、ISAバスに繋がっているが、ISAバスは
ISA-PCIブリッジによってPCIバスに繋がっている。
Legacy DMA転送は、PCIのこの転送機能を利用しているのだろうか?
>>558 そりゃブリッジがバスマスタになってごにょごにょしなけりゃ、
DMAにならんだろう。
>>559 PCIバスマスタ転送は、自動的にチップセットによってsnoopされ、
CPU内部のキャッシュと同期が取られるはずなので、
Legacy DMA 転送も、CPUの内部キャッシュと勝手に同期される
ということで正しいのだろうか。
されなきゃ8237直に叩くような行儀の悪いコードが 動かなくなってしまうのではないかと。 ISAのバスマスタなんてとんでもないモノは無理だと思うが。
>>561 てっきり、仮想8086モードでjmp far ptrを行うと、キャッシュや
パイプラインなどが実メモリと同期される性質(未確認)を使っているの
かと思ってますた。
チップセット内蔵の8237同等パーツは、今でも実メモリに直に繋がっている
ようにエミュレートされているのかと思ってましたが、そうではないの
かも知れませんね。
今は、絶対に、PCIのバスマスタ転送を利用していて、勝手にsnoopされて
いるんだという明確な証拠が欲しいですが。
少なくとも論理的にはPCIデバイスの先につながっているようになっている。 ちなみにキャッシュは気にする必要がない。そうでなければ既存のOSが動かなくなる。
>>563 便乗質問ですが、この場合CPUからの書き込みも何も気にする必要がないんでしょうか?
それともドライバーで何かの処理(DMAの領域はキャッシュ不可(ライトスルー)にする
等)が必要でしょうか?
ちなみにむかーし自分がm68kの乗ったマシンのドライバを書いた時はその手の処理を
したように記憶しています。今どき(?)のx86 & PCIのドライバに関してこの辺の知識を
得たいと思ったら何かお勧めの書籍等ありますかね?
ちょっと質問しまつ 使うアセンブラはyasm 汎用32ビットレジスタは eax,ebx,ecx,edx とかあるけど 汎用64ビットレジスタって rax,rbx,rcx.. .とか先頭にrを付けるのでいいのかな
ドキュメント読まないYUTORIか
>>566 読まないんじゃなくて読めない
ゆとりです
自己解決しますた
nasmのドキュメソトにレジスタ名載ってますた
>>566 d
ARMなんですが,実行ファイル(ELF)を無理矢理で良いので アセンブラの段階まで書き下してくれるようなソフトってすでにあったりしませんか? FF DE FF E7 FF DE ・・・・・・ ↓ bx lr なんていうかこんな感じで
>>569 あったな、あった。
昔はそんなの沢山あったな。
まあ、難しいもんでもないから自分で作ってみたら?
データとプログラムの区別とか、ジャンプテーブルの解釈がミソだぜ。
objdump -D
win32+VC++で、逆アセした関数をC++に組み込むのに安全で手っ取り早い方法を教えてケロ
MASMで書いてリンクじゃ駄目なの?
途中でdisassembleしている辺りが、被効率的杉で、ハナシにならない。
>>574 なにがどう違法行為なんだかw
もうすぐ合法になって、契約による縛りも無意味になるご時世だというのに。
被 -> 非 VirtualAllocで確保して、書き込んで、呼べばokな気がするする。
それだと使いたい所が空いてなかったら困らんかい? 適当にもらってから頑張って再配置とか。
>>577 それじゃ命令内のアドレスが無茶苦茶だろ。
(゚Д゚)ハァ? バカは死ね。
絶対ジャンプや静的変数の扱いをどうすんの。
関数に、そんなモノは無い。
゚o゚
572が想定している関数に、そんなモノは無い。 ...と書くべきだったか。
もちろん無いなら問題ないんだが、 どうして何の情報も出してない572の想定が分かるのだろうか。
『手っ取り早い』という条件があるからね。 とにかく、バカは死ね。
・・・これはひどい。
取り敢えず、>572が諦めれば済むな。
アセンブラを安全に使うなんて、無理だろ。つうか使う意味が無い。 危険だけど好きな事が出来るのがアセンブラの醍醐味なんだからな。
危険つっても攻殻機動隊の世界みたく脳が焼かれるわけじゃなし
無茶すりゃOSに怒られるしなあ…
MS-DOS の時代に比べれば、みんな安全なプログラムだよなぁ。
そうだねえ。 ハード叩きまくりだったからなあ。 再起不能になって修理するハメになったり…
32ビットは対象外かな?
いくらでもOK
アセンブラ勉強ならmasm使うべき
x86が基本ってことはないと思うが・・。
目の前にあるじゃない
基本中の基本ということなら68000かな。
600 :
,,・´∀`・,,)っ-●◎○ :2008/12/29(月) 09:11:44
そこはMMIXwareだろう
601 :
デフォルトの名無しさん :2008/12/31(水) 20:11:03
tasmとturbo debuggerが良い
はじめまして、最近になってインラインアセンブラの勉強をはじめた者です。 下記のような単純なコードを書いて文字列を出力させようとしているのですが、 どうしてもcore dumpが起こってしまいます。 単純な忘れ物をしているだけのような気がするのですが。。。。 なにか手がかりを教えていただけると助かります。 int main(void) { __asm__( "movl $0x4,%eax \n\t" "movl $0x1,%ebx \n\t" "movl $msg,%ecx \n\t" "movl $0x4,%edx \n\t" "int $0x80 \n\t" "msg: .string \"aaa\\n\" \n\t" ); return 0; } ちなみに環境はvine linux 4.2でgccでコンパイルをかけています。
>>602 int 0x80ってどのハードのどのOSのソフトウェア割り込みだよおい。
>>602 int $80はどこに戻ってくるでしょうか。
>>603 vineならlinux-x86と仮定してもいいんでないかい。
最近の OS でも、最終的には割り込みによる API って存在してるってのが主流なのん?
mkdir とか割り込みで実現してんのか。 じゃあ一瞬全処理止めてからディレクトリ作ってんの? まあ、自然に排他処理になるからいいっちゃいいけど、 止めなくてもいい処理も止まるよね。 でもまあ普通は激しく繰り返し実行するもんでもないから、 割り込みでも特に問題ないのかね。
608 :
602 :2009/01/03(土) 16:28:15
>>603-607 すばやいレス、ありがとうございます。
一応解決しました。
>>603 おっしゃる通り、linux-x86です。
>>606 ありがとうございます。
システムコールのwriteは実行していたのですが、
exitはしていなかったので追加したらcore dump
しなくなりました。
609 :
602 :2009/01/03(土) 16:28:50
これで正解かどうかわかりませんが一応コードを載せておきます。 int main(void) { __asm__( //システムコール(write)の設定 "movl $0x4,%eax \n\t" //出力先を標準出力に設定 "movl $0x1,%ebx \n\t" //出力文字の設定msg:aaa "movl $msg,%ecx \n\t" //文字列長の設定 3文字+改行 "movl $0x4,%edx \n\t" //実行 "int $0x80 \n\t" //出力文字はaaa\n "msg: .string \"aaa\\n\" \n\t" //システムコール(exit)の設定 "movl $0x1,%eax \n\t" //実行 "int $0x80 \n\t" ); return 0; }
んー。 最初の "int $0x80 \n\t" の割り込みが終了した後に "msg: .string \"aaa\\n\" \n\t" が「実行」されてしまうのが 問題なんじゃないの?
611 :
デフォルトの名無しさん :2009/01/03(土) 16:51:00
OS なしの状態で HDD 読み書きしたいんですけど、 どうやるか参考になるサイトとかありませんか? (要するに自作 OS とか作ってみたいのです)
念のため附記。 32-bit OS を作ろうとしています。
>>613 これって32ビットモードでも動きます?
>>610 が正解っぽいな。
>>607 > mkdir とか割り込みで実現してんのか。
mkdirに限らずシステムコールは全部割り込みでトリガするわけだが...
>>611 知らんけどOS30日本程度の内容はマスターしたの?
>>615 OS30日本は読んでます。
でも、この本だとディスク読み込みを
16-bit モードの間に全部やっちゃって、
あとは全くディスクアクセスしないんですよね・・・。
OSASK のコードでも読んでみるのが一番手っ取り早いんでしょうかね・・・。 ちと読んでみます。
618 :
602 :2009/01/03(土) 18:53:00
>>610 >>615 そうなんですか。
"msg: .string \"aaa\\n\" \n\t"
をインラインアセンブラの最終行に持ってくるのでしょうか。。。
とにかく、まだ理解不足なので勉強を続けたいと思います。。
620 :
602 :2009/01/03(土) 19:19:54
>>619 アドバイス、ありがとうございます。
このような具合でしょうか?
ただ、終了処理を入れないとやはりcore dumpしました。
int main(void)
{
__asm__(
//出力文字はaaa\n
"msg: .string \"aaa\\n\" \n\t"
"jmp shori \n\t"
//文字列出力処理
"shori: \n\t"
"movl $0x4,%eax \n\t"
"movl $0x1,%ebx \n\t"
"movl $msg,%ecx \n\t"
"movl $0x4,%edx \n\t"
"int $0x80 \n\t"
//終了処理
"exit: \n\t"
"movl $0x1,%eax \n\t"
"int $0x80 \n\t"
);
return 0;
}
>>620 ああもう。msg を飛び越えるように jmp しろと。
あるいは return の後ろに msg 書け
FDC というのをいじればディスク操作ができるようですね。 いじり方がまだよく分からないのですが、 糸口は見つかったので頑張ってみます。
624 :
602 :2009/01/03(土) 20:02:40
FDC はフロッピーだけみたいだけど、
HDD 扱いたいのでやっぱ FDC のサポートは後回しーってことで、
HDD は IRQ 14, 15 (IDE コントローラ)を通じて扱えるっぽい、と、
>>623 を見て混乱する人がいないように、念のためメモ。
BIOS が使えるなら、拡張 INT 13h でおk、と。
シーク・セクタ同期待ち・DMA転送とかを全部自分でやるんじゃないの?
ディスクの話題が続くようならOS板の適当なスレに移動してね。
実際に使う事を考えたら、特定のハードウェア寄りの話になるのは 仕方のないこと。
>>624 もう見てないかもしれないけど
この場合、プログラムの終了ステータスは何になるか、わかってるのかな。
やたらタブとか入ってるのは、単にコンパイルするだけじゃなくて gcc の中間出力を
見るためなんだろうなあ。だったら最初からインラインじゃなくて普通にアセンブラで
書けばよくね? gcc が補ってくれる「余計な」部分が入らなくてスッキリすると思うw
Vine Linux 4.2 だとカーネルは 2.6 系列みたいなので、システムコールには
int 0x80 以外にも sysenter が使える。後者の方が今は主流だと思う。
複数行asmの終端は"\n\t"が普通じゃないかい。 "\t"入れないとgasが文句言ってきたような気がする。 sysenterはPentiumで試したらSIGILLしました。 とか突っ込まれることになるので、お遊びレベルならintでいいんでないかと。
>>633 >"¥t"入れないとgasが文句言ってきたような気がする。
ああそういう積極的意味があったのですか。
>sysenterはPentiumで試したらSIGILLしました。
>とか突っ込まれることになるので、お遊びレベルならintでいいんでないかと。
確かに。不確定な要素はなるべく減らした方がいいですね。
特に最初のうちは、その位のことでも何が悪いかわかるまでに猛烈に時間がかかったり
するし。人によってはそこで game over。
まあそういうのが訓練になるとも言えるのだが。
635 :
デフォルトの名無しさん :2009/01/16(金) 15:54:30
質問なのでage 質問スレから誘導されてきますた さっぱりわからないので一部でもいいので解き方をお願いします 一問目 0100 MOV AX,5 AX= 二問目 0100 MOV AX,A 0103 ADD AX,5 AX= 三問目 0100 MOV AX,C 0103 SUB AX,5 AX= 四問目 0100 MOV AX,4 0103 SHL AX,1 AX= 五問目 0103 MOV AX,F 0103 CMP AX,5 AX=
それを電話で質問されるって一体どんな状況だ 一問目は解いてもらってるだろ ADDは加算、SUBは減算、SHLは指定されたビット数だけ左シフト、CMPは二つの数を比較 x86のアセンブラの本を一冊買って勉強汁
>>636 ありがとうございます
愚妹が大学の授業で(一応)やったらしいのだが、試験前になって全くわからないから兄さん助けてとorz
話を全く聞いてなかったんだろうな
それで兄が頑張って理解しようとしているわけです
やっぱり本買ってくるわノシ
638 :
デフォルトの名無しさん :2009/01/16(金) 21:03:32
>>635 です
本を読んで何となくの概念と一問目と四問目はわかりました
が、それ以降は相変わらずorz
二問目
0100 MOV AX,A
0103 ADD AX,5
AX=15([F])←ここの表記は曖昧
の場合はAをAXに移動してAと5を足してAXの欄に書くっていうことだよな?
どこからこの答えが出たのか教えて
三問目
0100 MOV AX,C
0103 SUB AX,5
AX=7
CをAXに移動してCから5を引いてAXの欄に?
五問目
0103 MOV AX,F
0103 CMP AX,5
AX=(15[F])
FをAXに移動してFと5を比較して値が同じならZF=1?
俺の頭じゃどうしても答えにたどり着かないわorz
A=10 A+5=15 C=12 C-5=7 F=15
>>639 16進数を10進数に直したってこと?
それならわかったわ
ただ五問目もうすこしkwsk
比較したのに15のままなのが?
比較したってAXの値が変わるわけじゃないでしょ
確かにw これで半分終了…あと五問あるぜorz 問A 4×8(4を8回足す)計算 一問目 0100 MOV AX,0 0103 MOV BX,8 0106 ADD AX,4 0108 DEC BX 0109 JNZ 0106←本来の問題ではここを選択して書く 俺の考え 0をAXに、8をBXに移動 4の16進数4をAX=0に加える BX=8から1を引く それが0じゃなければ0106へジャンプ?←どうしてこれが選ばれるかさっぱり 二問目 0100 MOV AX,0 0103 MOV BX,0 0106 ADD AX,4 0109 INC BX 010A CMP BX,8 010D JNE 0106←本来の問題では(ry 俺の考え 0をAXに、0をBXに移動 4の16進数4をAX=0に加える BX=0に1を加算 BX=1と8を比較 等しくないならジャンプ?←どうしてこれが(ry
問B 1から15の正数の足し算 一問目 0100 MOV AX,0 0103 MOV BX,F 0106 ADD AX,BX 0108 SUB BX,1 010B JNZ 0106 0をAXに、FをBXに移動 BX=FをAX=0に足す(Fは10進数で15だから15?) BX=Fから1を引く(14?つまりは16進数だとE?) 0じゃなかったらジャンプ←まず何が0じゃなかったら? 二問目 0100 MOV AX,0 0103 MOV BX,F 0106 ADD AX,BX 0109 DEC BX←本来ここを書く。なんでこうなる? 010A JNZ 0106 基本的に一問目と同じ程度の考えしかないorz
問A 4×8(4を8回足す)計算 一問目 BXは後何回4を足すかっていうカウンタ AXに4を足す BXから1引く を繰り返し BXが0になったら終わり 二問目 BXは何回4を足したかっていうカウンタ AXに4を足す BXに1足す を繰り返し BXが8になったら終わり 問B 1から15の正数の足し算 一問目 BXをAXに足す BXから1引く の繰り返し BXが0になったら終わり 最初15を足して 1引いた14を足して 1引いた13を足してって AX=15+14+13+....+1 二問目 0109 DEC BX と 一問目の 0108 SUB BX,1 は同じ BXから1引く
int ax = 0; int bx = 8; while (bx != 0) { ax += 8; bx--; }
>>642 最初に ax を初期化(=0)して、そこに、8回分4を出していくわけだ。
最初は bx == 8 だけど、dec すると、bx は 8→7,6,5,4... と減っていく。
※ bx は『あと、bx 回処理をする』という意味。
だから、あと1回以上処理をするなら、ax を加算しているアドレス0106h に戻るわけだ。
下のほうは、『これまでに、bx 回処理をした』って感じで数え上げている。
最初は bx == 0 だけど、0 → 1, 2, 3,... 。
だから、まだ8回処理していないなら、アドレス 0106h に戻れっと。
>>642 一問目の 8 から数え下げる方法と、0 から数え上げる方法では、"cmp bx,8" を省略できるので、上のほうが上級者っぽい。
>>643 "sub bx,1" よりも "dec bx" のほうが、命令長が1バイト短い。(8086 あたりならdecのほうが速い)。
だから、特別な意図が無い限りワード命令の場合、sub より dec を使う。
スマソ寝てたorz これから俺の足りない頭で愚妹のために解説プリント作ってくるわ またわからないことがあったら質問させてください 本当にありがとうございます
649 :
デフォルトの名無しさん :2009/01/17(土) 08:55:32
一問見落としてたorz 11の2乗のプログラム 0100 MOV AX,0 0103 MOV BX,B 0106 ADD AX,BX 0108 ADD AX,BX 010A DEC AX 010B DEC BX 010C JNZ 0106 これを参考に8の2乗のプログラムを作成しなさい これは全くもってさっぱり どのあたりが11の2乗なのかもわからないorz
>>649 16進数に慣れておく必要があるな。
11はb(16)となる。
つまり、mov bx, bで11を代入しているわけだ。
他を見てないのだけど、一応C風に書き直すとこうなる。
ax = 0;
bx = 11;
do {
ax += bx;
ax += bx;
--ax;
--bx;
} while (bx != 0);
これを更に書き直すとこう。
ax = 0;
bx = 11;
do {
ax += 2 * bx - 1;
--bx;
} while (bx != 0);
これを展開すると、
ax = (2 * 11 - 1) + (2 * 10 - 1) + ... + (2 * 1 - 1);
となって、
ax = 21 + 19 + ... + 1;
となり、これは当然121になる。
つまり、奇数列の初項からの部分和が平方数になることを利用しているわけだ。
要は8の2乗にしたいのなら、単純にmov bx, 8でいい。
>>650 C言語もよくわからないけどなんとなくわかってきたw
ただADDの列が2回ある意味がわかりませぬorz
大切なことだから2度言いました、が思い浮かぶ…w
だから、ax = ax + 2 * bx - 1なんだってば。 試しに、(逆順になるけど) 1 + 3 + 5 + 7 + 9 + 11 + ... って計算を手でしてご覧。 1, 4, 9, 16, ... って風に平方数が出てくるのが判るべさ。
信じられないほどくだらない問題だな。 二乗を求めるために、わざわざ級数の総和をループで計算することに何の意味があるんだ。 作った奴の頭の悪さ、自己顕示欲の強さがまる見えだ。 こんな手法が必要になる状況なんて西暦5000年になっても来ないに決まってる。 代わりにもうちょっとマシな問題を。 昔のCPUは掛け算が出来なかったので、加減算を組み合わせて掛け算を行っていたことがある。 たとえばPC8001は(古いな)、画面一行に120バイト必要としていたため、120倍の計算をする 必要があったのだが、入力を120回加算していてはただでさえ遅いCPUがますます遅くなる。 そこで、ループでない方法で、掛け算を使わず、出来るだけ高速に、 入力を120倍する計算を行うサブルーチンを作れ。
>>652 ごめんな、ものわかり悪くてorz
ようやく理解しますた
>>653 しょせん小娘たちの試験問題だからこういう問題なんだと…
もっと実用的なものやってほしいわ
>>653 当時はビットシフトも1つずつしかできなかった、という条件も必要では
それ以前に8ビットCPUだし
>>653 >必要があったのだが、入力を120回加算していてはただでさえ遅いCPUがますます遅くなる。
いや、それはCPUに対して失礼だ。CPUが遅くなるわけじゃないからな。
同じことをなんどもやらされるとうんざりして仕事をサボるCPUたん
LD H,A LD L,0 SRL H RR L ;HL = A*128 RLCA RLCA RLCA LD E,A LD D,0 ;DE = A*8 AND A ;CF=0 SBC HL,DE RET
A>=32のときバグるじゃん
>>659 LD L,A
LD H,0
ADD HL,HL
ADD HL,HL
ADD HL,HL
LD E,L
LD D,H ;DE = A*8
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL ;HL = A*128
AND A ;CF=0
SBC HL,DE
RET
mov ax,10 ; 初期値 511 迄対応 add ax,ax ; 2倍 add ax,ax ; 4倍 add ax,ax ; 8倍 mov dx,ax ; dx == 8倍 add ax,ax ; 16倍 add ax,ax ; 32倍 add ax,ax ; 64倍 add ax,ax ; 128倍 sub ax,dx ; 120倍 8086 に直すとこういうことか。
128倍してから8倍を引くと 128倍でオーバーフローするかもしんないぜ。
最大値が 546 と 511 の違いだね。
255 まででいいのなら mov ah, al shr ax, 1 で 128 倍できるぜ。
mov ah,al は 129 倍だ。
ちがう。257倍だった。
xor al, al を忘れてた
div/idiv 使わずに、ax を 10 で割ってください。ax==365 で 36 になればいいです。
cmp ax, 365 jne hoge mov ax, 36 hoge:
かけ算は使っていいのか?
mul/imul も禁止
ついでに加減算も禁止。
ビット演算オンリーか。
誰か答え書いてよ 寝れないじゃないの
流石に加減算を禁止されては・・・
full adder を論理演算で作るんだ
>>653 > 二乗を求めるために、わざわざ級数の総和をループで計算することに何の意味があるんだ。
> 作った奴の頭の悪さ、自己顕示欲の強さがまる見えだ。
> こんな手法が必要になる状況なんて西暦5000年になっても来ないに決まってる。
ループのプログラムの例題として、ふつーこんな求め方しねーだろwwww なものを
使うのはよくあると思うぞ。まぁそうでないものを例に使う方がいいとは思うが。
突然えらく伸びててびっくりした
679 :
デフォルトの名無しさん :2009/01/20(火) 01:18:01
mov ax,365 xor dx,dx @@: cmp ax,10 jb @f sub ax,10 inc dx jmp @b @@: xchg ax,dx これでいいの?識者の方デバッグして さすがに加減算はいるよ。
bush obama
いらない報告を この前手取り足取り教えていただいた兄です 愚妹から100パーではないけど意味がわかったおかげでそれなりに解けたと連絡が来ました 本当ありがとうございました
683 :
デフォルトの名無しさん :2009/02/07(土) 12:37:36
LD命令とMOV命令があって楽しい 時々CASLも書いてある
x86に下限0上限100の飽和演算ができるSIMD命令はありますか?
685 :
,,・´∀`・,,)っ-●◎○ :2009/02/08(日) 04:57:41
paddusb/psubusbを使えば0下限255上限で飽和処理をしてくれる。 更にpminubを使って100との比較をし、上限100に切ればいい。
それやったらものすごく結果が変わってしまうと思うが。
687 :
,,・´∀`・,,)っ-●◎○ :2009/02/08(日) 05:26:49
お前は何を言ってるんだ
689 :
,,・´∀`・,,)っ-●◎○ :2009/02/08(日) 05:36:50
0−100の飽和って何に使うのかさっぱりわからんが
上限下限のチェックするのがめんどくさいだけなんじゃない?
足してから毎回101で割るとか(w
確率計算かね
やはり命令一発では無いですか。
>>685 をやってみます。ありがとうございました。
やりたいのはADPCMデコードの高速化でした。
数MHzの8bitCPUでADPCMいじってる俺からすりゃものすごい贅沢だよ…
ADPCMでSIMDを使うっていうのが、イミフメ。
イミフメの理由がイミフメ
697 :
デフォルトの名無しさん :2009/02/10(火) 00:08:01
MS-DOS 5/6 あたりで実行できる16BITバイナリが作成できる、フリーのCコンパイラで良いのありませんか? 今もっている MS-C 6 は、PC-98 用なので、x87 命令の関係で PC/AT では難があるのです。 MASM で作った関数がかなりたくさんあるので、できれば、MS-C 互換のものが良いです。
今はobjdumpしか使ってないんだけど、 もっと本格的に解析できるのはなんかある? フリー&&オープンで。
>>697 gccとNASMの組み合わせじゃダメ?
DOS用にリンカスクリプトとcrt書けばx86向けの奴でいけたはず。
>>697 このスレ的な解法を提示すると
emoem.asm をいじればIBM-AT互換機用にできる。
704 :
デフォルトの名無しさん :2009/02/20(金) 06:26:06
エスパーよろしく!!
>>668 axを25.6倍してから、256で割る(
>>8 する)。といいたいけど、ちと誤差が多いので、
51倍(≒25.6×2)してから、512で割る(
>>9 する)。オーバーフローに注意。
掛け算も禁止なら、左シフトと加算で臨機応変に。
って、いまさらだれも見とらんか。。。
680でもう出てる気がする
1010bで割るのに特化した書き方できないかな。除算ループの中を2回だけ、みたいな。
709 :
708 :2009/02/21(土) 15:51:07
「5で割る」 演算ができればいいんだ。/4と/1(=元の数)を引く演算ができないかな。
読み始めてから分かったのだけど『Assembly language step-by-step』って出版されたのは2000年だけど執筆されたのはWindows NTの時代。 最近の話題で覚えた方が良いよってのがあったら教えてください。 (それにしてもアセンブリ言語関係は最近の和書が少ないですね)
>>712 。この本
ハッカーのたのしみ―本物のプログラマはいかにして問題を解くか
714 :
:2009/02/25(水) 21:36:57
MASMで勉強始めました。 pushに即値をオペランドとして渡すことはできないのですか? インテルのIA32のマニュアルでpushの項目に 6A PUSH imm8 imm8をプッシュする と書いてあるのでできそうに思えるのですが たんにpush 08H とかしてもエラーになります。 型がわからないからエラーになるのか、それとも即値ではいけないのでしょうか?
今は即値pushできるはずだけど、 16bit時代はできなかったと思う。
先頭に .186って書け
717 :
:2009/02/25(水) 22:02:37
>>715 MSDOSの16bit用のを書いてました。
でも
>>716 さんの言うとおりするとできました。
.186ってことは8086じゃできなかったけど80186からできるようになったということですね。
ありがとうございました。
718 :
:2009/02/25(水) 22:16:46
でもバイトの即値をpushしてもスタックにつまれるのはワードで、popもバイトのレジスタへのはないんですね。 まあ目的もなしに勉強してるだけだから困るわけじゃないけど。
719 :
:2009/02/26(木) 02:08:02
16ビットMSDOS用のアセンブラをコンパイルしてXDAっていうやつで逆アセンブルすると ヘッダの情報のところに Relocation data = Offset:x001E, size:x0004 ってあるんですけど、これは何を意味してるんですか? Offset:x001EはIMAGE_DOS_HEADER構造体のe_lfarlcの値らしいのですが 最初のリロケーション項目のオフセットっとかいう説明を読んでも、どういう意味を持つのかわかりません。
>>719 ローディング時に値を設定する必要があるセグメントアドレスへのポインタリストのファイル内オフセット。
セグメントアドレスの個数はe_crlc。
かな?
16ビットアドレスを使っているところはセグメントレジスタのセグメントアドレスと+して物理アドレス とする。プログラムのなかでセグメントアドレスを使用している部分。このセグメントアドレスは ローディング時に値が決まるのでローダーが値を書き換えて上げなければならない。 その値を書き換えるべき対象のポインターリストが「リロケーション項目」。
722 :
:2009/02/26(木) 08:51:17
>>720 >>721 どうもありがとうございます。
1Eとあったということは、ファイルの先頭から1Eバイト目を指しているということで
そこを見ると07とありました。
ファイルの先頭から1Eバイト目には、IMAGE_DOS_HEADER構造体のフィールド e_res[4];// Reserved wordsがくるはずで
予約領域で常に0に設定されてるとか解説してるWebページをみましたが、
自分のプログラムをコンパイルした結果は値が設定されてるのはなぜかと思ってましたが、この値なのですね。
link16でリンクしたからその結果なのでしょうか。他のプログラムは1Eじゃなく40がほとんどでした。
で、そこにある値07の意味なのですが、自分の書いたコードがマシン語になった7バイト目は
mov ax,dsegという命令のdsegにあたる部分で、DSの値がくるはずのバイトでした。
ここをさしていると考えていいみたいですね。たしかにロードされた場合、そこは実際のDSの値に書き換えなくちゃいけませんからね。
723 :
:2009/02/26(木) 08:59:39
実際のDSの値 ではなく 実際にDSに設定する値 と表現するべきでしたね。
724 :
:2009/02/26(木) 09:02:51
assume cs:cseg,ds:dseg,ss:sseg としてましたから。
BIOSのシステムコールの0x18が使い方わからん・・ 教えてくれ
いや、OS作ってるんだけどさ 0x18で確か・・周辺機器リストの取得だったはず
ビットフィールドってどうやって取得すればいいんだ?
してシフト
分岐に使うのか演算に使うのか
>>729 LSB 側にフィールド位置だけよせて, フィールドサイズの 1 のビットを
積めたもので and を取れと言われてるんだが, この説明で分かるか?
>>728 検索してみると、INT18 Device ってのもあるらしいんだが...
ネットワークブート?
質問です。ちょっと長いので2分割しますが、すいません。 PC-9801/PC-9821上のNASM 2.06rc1で組んでますが、より効率の良いコードを 考えていて、詰まりました。Cだとif〜elseでイケますが、アセンブラの場合、 共通のルーチンがある場合、どうしたらいいでしょうか。 単純にjmpすればいいのでしょうか?ただ、それだと若干メモリとかコードが 大きくなってしまうような気がします。要点は、 1)mov ax,4c00h int 21hのDOSコールが2箇所ある。無駄すぎ。 2)mov ah, 9 int 21hのDOSコールが2箇所ある。やはり無駄っぽい。 3)messageの中身は、実際は数値の違いだけ(2MHzか2.5MHzか)。これを 集約できないか。なんとかできないでしょうか。以下、例示します。 PC-9801/9821用 SysClk.asm ; システムクロックを取得する (タイマIC 8253Aより) NASM 2.06rc1用コード ; PC-9801 system clock diagnostic program ; tested on PC-9821Xa7e(430FX)/PC-9801DA2 ; ; Programmed by Yamato_Damashii 2009-02-27 for NASM 2.06rc1 [Bits 16] org 100h ; COM program start: push es xor ax, ax mov es, ax ;------------------------------------------- ; 0000:0501h = BIOS_FLAG ; bit 7 = System Clock ; if bit 7 = 0, then system clock is 2.5MHz ; if bit 7 = 1, then system clock is 2MHz ;------------------------------------------- test byte [es:0501h], 80h ; hex 80h = byte 10000000 pop es jz sysclk_is_2_5MHz
続き sysclk_is_2MHz: mov ah, 9 mov dx, message_2MHz int 21h mov ax, 4c00h int 21h sysclk_is_2_5MHz: mov ah, 9 mov dx, message_2_5MHz int 21h mov ax, 4c00h int 21h message_2MHz: db 'System clock is 2MHz', 0dh, 0ah, '$' message_2_5MHz: db 'System clock is 2.5MHz', 0dh, 0ah, '$'
うーむ・・さっぱりだ
>>740 これでいいんじゃないかと
test byte [es:0501h], 80h
pop es
jz sysclk_is_2_5MHz
mov dx, message_2MHz
jmp print_sysclk
sysclk_is_2_5MHz:
mov dx, message_2_5MHz
print sysclk:
mov ah, 9
int 21h
mov ax, 4c00h
int 21h
>>744 ありがとうございます。ご提示の案、検討してみます。
>>742 callでも検討を考えていました。コードが若干複雑になる可能性がありますが、
(僕の頭が単細胞…(^^;)、call〜retでサブルーチン可してしまう案ですよね。
ありがとうございました。
がんばります。次はサウンドBIOSの有無のチェックや内蔵固定ディスクの切り離しの有無の
チェックプログラムのコードに取り掛かります。
たかだかそれくらいならcallする方が無駄な気がするぞ。時間とか電力とか。 俺ならマクロで書いてしまう。 NASMって知らないんだけどマクロアセンブラじゃないの? ならm4なりcppなりのマクロプロセッサをかますとか。
>>746 NASMはもちろん、マクロアセンブラですよ。オープンソースです。
ZSNESとかはCとNASMで書かれてます…。
ただ確かに、超小規模なんで、call〜retは無駄すぎますね。
実はNASMでのCOMコードをようよう書けるようになった程度なんで、
まだNASMの実装する膨大なマクロ機能などはMANUAL未読部分で、
org 100h〜mov ax, 4c00h int 21hで小さなチェッカツールを作るのが
関の山で。精進します。
なんでNASMの解説してくれてるんだろうか
クラスタサイズ以下にしてもあまり意味がないと思うけど、それはおいといて esを保存する必要はないし、最後はretでいいと思う
athlon64用のコードを逆アセンブルするとでてくるnopwとかretqって何でしょうか? amdのサイトにあるamd64のインストラクションセットマニュアルには載ってませんでした
752 :
750 :2009/03/23(月) 11:33:22
AT&T形式のアセンブラだとニーモニックの後ろにオペランドサイズがつくって話か?
long NOPの一種だと思うが該当部分のオペコードが無いと判断できない
名前からして nopw:nopのWORD retq:retのQ? だな。qってなんだろ?
quad じゃね?
qwordだろ
環境:MASM 9.0 以下のコメントアウトされたプロトタイプで 最初の2つはOKだが3つめは何故エラーになるのでしょうか error A2008: syntax error : title ;func proto STDCALL , :dword , :dword ;func proto STDCALL , message:dword , :dword ;func proto STDCALL , message:dword , title:dword .code func proc mes : dword , tit : dword invoke MessageBoxA , NULL , mes , tit , MB_OK ret func endp 他2つではちゃんと実行出来ます リファレンスには label PROTO [[distance]] [[langtype]] [[, [[parameter]]:tag]]... とあるのでどれでも動きそうに思うのですが
予約語
>>725 なんの機種かわからんが古いのならROM BASICだったような。
質問させてください
以下参考にHelloWorldが動くところまで出来ました
ttp://www.masm32.com/teaching/index.htm しかし、printfのために色々インクルードされてて自作感があまりないです
print関数をもっとシンプルにCPUの機能(dosのint 21hみたいな感じ)で
実現することって出来るんでしょうか?
(それともint 21h自体も何かの機能で実現されている?)
まずは1文字だけでもいいので表示したいのですが
例えばこんな感じのことは出来ますか?
.386
.model flat,stdcall
.data
msg db "hello world",13,10,"$"
.code
start:
mov dx,offset msg
mov ah,9
int 21h
end start
(書き込み規制中で代行お願いしてます)
>>762 WindowsのDOS互換機能で実行してるなら、DOSのファンクションが実行できる
はずだからやってみたら?
INT 21hがなんなのか知りたければ、CPUとOSの勉強をしてください。
いずれにしても、そういう低水準のことを希望するなら使ってるプラットフォームに
ついて調査することは基本。どういうシステムの上での話か説明できていない点で、
その質問のしかたからしてダメダメです。
インクルードファイルを辿って行けば?
765 :
デフォルトの名無しさん :2009/04/03(金) 14:46:42
878 :Classical名無しさん :09/04/02 23:54 ID:31nUMIMQ
お願いします。
【URL】
http://pc12.2ch.net/test/read.cgi/tech/1172916032/ 【名前欄】
【メール欄】sage
【本文】↓
質問させてください
以下参考にHelloWorldが動くところまで出来ました
しかし、printfのために色々インクルードされてて自作感があまりないです
print関数をもっとシンプルにCPUの機能(dosのint 21hみたいな感じ)で
実現することって出来るんでしょうか?
(それともint 21h自体も何かの機能で実現されている?)
まずは1文字だけでもいいので表示したいのですが
例えばこんな感じのことは出来ますか?
.386
.model flat,stdcall
.data
msg db "hello world",13,10,"$"
.code
start:
mov dx,offset msg
mov ah,9
int 21h
end start
暇人乙
マジキチ
下手の考え休むに似たり。
それはつまるところテキストVRAMに書くんだよというような話を聞きたい人なのかな。
771 :
762 :2009/04/04(土) 10:47:59
色々ありがとうございます。すみません、環境も書きます
WinXP/Pentium Dual-Core E2180/AMIBIOS(2006)
まず、最終目標はOS作成(動作原理が知りたい)です
(なので、DOSにも頼らない方向にしたい)
あれから、int 21HもCPUの機能ではなくて
OS側の機能ということがわかりました。
ttp://7ujm.net/nasm/4.html そこで、BIOSを使えば文字が表示出来ると思いましたが
以下コード、Win環境では実行すると例外が出ます
〜略
mov ah,0eh
mov al,61h
mov bh,0
mov bl,1
int 10h
このコード、ブート直後ならいざ知らず、
Win起動後はOSの保護で例外がでると
推測したのですがあってますでしょうか?
Winのcmd.exeで試行錯誤しながらOS作って、
それでいつかブートするのが理想なんですが
BIOSが直接たたけないとなると次はエミュですかね・・
773 :
代理 :2009/04/04(土) 11:10:26
>>771 70 :Classical名無しさん :09/04/03 22:55 ID:M4Y7rn8Y
荒らし対策になるか、ちょっとテストもかねて
これでお願いできますでしょうか。
ゆあるえる
http://pc12.2ch.net/test/read.cgi/tech/1172916032/ なまえ 762
めーる sage
ほんぶん
色々ありがとうございます。すみません、環境も書きます
まず、最終目標はOS作成(動作原理が知りたい)です
(なので、DOSにも頼らない方向にしたい)
あれから、int 21HもCPUの機能ではなくて
OS側の機能ということがわかりました。
そこで、BIOSを使えば文字が表示出来ると思いましたが
以下コード、Win環境では実行すると例外が出ます
〜略
mov ah,0eh
mov al,61h
mov bh,0
mov bl,1
int 10h
このコード、ブート直後ならいざ知らず、
Win起動後はOSの保護で例外がでると
推測したのですがあってますでしょうか?
Winのcmd.exeで試行錯誤しながらOS作って、
それでいつかブートするのが理想なんですが
BIOSが直接たたけないとなると次はエミュですかね・・
暇人乙
エミュがどうしても嫌、どうしても実機でっていうんだったら まぁそれなりに手もないではないけど、そうでなければとりあえず エミュを触ってみたら? あと、テーマ的にかぶると思うんだけど、OS30日本は知ってる?
>>773 >最終目標はOS作成(動作原理が知りたい)です
Linuxでも読みなさるがよいでしょう。
C++で書いた関数をSSEとか使いたいからアセンブリで書こうと思ったんだが 例えば struct hoge { int hoge1; ... }; void hoge_func( const hoge &hogehoge, const hoge &hogehoge2, int hoge2 ) { ... } って言うのだったらそれぞれの引数にはどうやってアクセスしたらいい? ちなみにアセンブラはnasmで(それ以外の構文は知らないorz
C++? アセンブラとやりとりとかしたいんならCをすすめる。 んで、 C→アセンブラ 呼び出し C←アセンブラ 情報にアクセス 方向はこういうことでいい? つまり hoge_func の中身をアセンブラで書きたいということでいい?
779 :
777 :2009/04/04(土) 14:34:32
一応参照を渡してるんでC++って書いたんですけど、アセンブラで書くときにポインタと同等というならつまりは void hoge_func( const hoge *hogehoge, const hoge *hogehoge2, int hoge2 ) って関数の中身をアセンブリで書きたいって事です。 VC9のアセンブリ出力してもサパーリでorz mov eax, dword ptr _hoge2$[esp+44] とか... アセンブリ出力とデバッガでの逆アセの内容って違うんですねぇ→もっとわからなくなってきた
参照のコーリングコンベンションとか実は知らないんでアドバイスできないというだけなんだけど。
あと C++ は名前をいじるから、アセンブラとのやりとりは面倒になる。
>>779 > アセンブリ出力とデバッガでの逆アセの内容って違うんですねぇ→もっとわからなくなってきた
基本的にはそんなに違わんのだが、細かい所はいろいろある。
VC++ なら、拘らないんなら MASM 使ったほうがいいんでないかなぁ。
実際に比較したことはないんでちょっとわからないけど。
それと、インラインアセンブリは検討した?
処理内容が画像なり音声なりの巨大データの操作なのでSSE3以降も使いたいんですよ MASMがどこまで対応してるかわからんのですが、VC++のプロパティ見る限りSSE2までなんで まーある程度わかるNASMでいけたらなーって感じだったんですよ
>>777 呼び出し規約とかでググれ。
あと、SSEを使うことが目的なら、アセンブリ言語に限らず、
組み込み関数を使うという手もある。
>>777 とりあえず、extern "C", __cdeclでOK。
構造体の使用は、面倒だから、オススメしない。
784 :
777 :2009/04/04(土) 16:42:45
わかりました とりあえず呼び出し規約あたりで調べてみます
>>771 お前が抜粋した部分だけをCOMとして作って実行すれば、例外にはならない。
いや、「OSの保護で例外がでる」というのは大正解だが、
その例外はWindowsのDOS実行環境が捕まえて、
DOS窓へ文字が出力されるという所定の動作になる。
例外になりましたが・・ >a.com --------------------------- 16 ビット MS-DOS サブシステム --------------------------- C:\WINDOWS\system32\cmd.exe - a.com NTVDM CPU は不正命令を検出しました。 CS:2725 IP:0125 OP:63 75 6d 65 6e アプリケーションを終了するには、[閉じる] を選んでください。 --------------------------- 閉じる(C) 無視(I) --------------------------- コード(a.asm) .MODEL small .code start: mov ah,0eh mov al,61h mov bh,0 mov bl,1 int 10h end start command.comで実行しても同じ しかし、これだけ作るのにめちゃ調べた アセンブラは敷居が高過ぎる
int 10Hの直後、ah=4cHでint 21Hするべき。
ありがとうございます。 おそらく、WinでいうExitProcessみたいなものが 抜けてたわけですね cmd.exeでは動きませんが command.comのほうで無事動きました。 次は、フロッピーのブートイメージとして使えるcom作りを頑張ります (サンプルプログラムがないので このためだけにMASM→NASM乗り換えを検討してます)
789 :
785 :2009/04/04(土) 20:56:08
>>787 あーごめん、自分もそれやっていたの忘れていた。
OS自作入門をMASMで進めてるんですが 次の命令はMASMではどう書けばよいのでしょうか RESB 0x7dfe-$ ; 0x7dfeまでを0x00で埋める命令 DB 7dfeh - $ dup (?) とすると error A2094:operand must be relocatable となります。7dfeh - $の部分が置かれる場所によって異なる結果になるから 無理、ということなんでしょうか?
operand must be relocatable を素直に解釈すると、 引数に絶対アドレッシングは使えません、てことなのだが。 てか30日本てMASMじゃなくてnasmだっけ? とくに理由がなければ同じツールを使えばいいと思うんだけど。
すみません、'$'とすることで自己解決しました 本のは、naskっていうnasm系の独自アセンブラみたいです
それは解決してない気がするぞ。
>>790 org 7dfeh
でいいんでないかい。
そこなら0で埋める必要もなかろう。
出来たと思ったらバグってたんですが 出来ました!ありがとうございます。
エミュで、フロッピー起動して動くプログラムが書けるようになってきたんですが どうしてもわからないところがあるので質問させてください 以下のプログラムは1バイトのレジスタを受け取って そのアスキーコード値を表示するサブルーチンで 一応動作はしてます。 しかし、16ビットの場合スタックはワード単位だと思うので ※1の所はbx+4ではなくbx+2だと思うのですが そう変更すると動作しなくなります また、※2の箇所はret 4にしても何故か動作するため 何が正しい挙動なのかさっぱりわかりません 直感的には※1も※2も2だと思うのですが どこが間違ってるのでしょうか? pchar PROC NEAR STDCALL push bx mov bx,sp mov al,byte ptr [bx+4] ;※1 mov ah,0eh mov bh,0 mov bl,1 int 10h pop bx ret 2 ;※2 pchar ENDP 呼び出し mov ax,0061h ;'a'のアスキーコード push ax call pchar
1. bx+0が元のbxの値、bx+2がリターンアドレス、bx+4が第一引数。 2. 異常が起きてても気づいてないだけ。
なるほど、把握しました。 自分は富豪的プログラマなので こうするのが性にあってるようです。 pchar PROC NEAR STDCALL push bx push ax mov bx,sp mov al,byte ptr [bx+6] mov ah,0eh mov bh,0 mov bl,1 int 10h pop ax pop bx ret 2 pchar ENDP アセンブラに慣れてる人はどの程度レジスタやらを 保存させますか? そういえばEFLAGSなんてのもあるんでした 今後自分が書くサブルーチンは 全部こんな関数になりそうですわ そういう意味で、fastcallにはあまり魅力を感じない stdcall(・∀・)イイ!
axを保存することのどこが富豪的か分からないが、 axは戻り値にも使うから(戻り値のない時でも)保存しないのが普通。 あと、その用途で使うのはbxよりもbpでしょ。
axを保存、というか、関数内で使うレジスタ全部保存って意味です どうも、レジスタやらが勝手に破壊されるのが嫌なんで。 保存しとけば全部ローカル変数のノリで使えるので 疑似コードですが、例えばax保存したら printnibl proc push ah ;上位ニブル。実際はちゃんと計算する call pchar ;上位ニブルを表示 push al ;下位ニブル call pchar ;下位ニブルを表示 hoge endp こんなんも気兼ねなく書けるかなと。 しかし戻り値のことを忘れてました 即値では戻ってこないですもんね axだけは破壊的な変更を許して 他は全部保存、ぐらいが富豪的妥協ポイントでしょうかね >bxよりもbpでしょ ご指摘ありがとうございます。精進します
dxも保存しないほうが多いと思う。ax:dxのペアで32ビット値を戻すのに使う。
たった1文字画面に表示するだけの処理にいちいちどうでもいいレジスタまでpush,popするようじゃ無駄が多すぎるだろ。 1000文字表示させたらどんだけ無駄な処理になるか考えてみれ。 無駄が多いってことは遅いってこと。アセンブラはCより速くて効率が良く、小さく作れるところが売りなんだから わざわざ遅くなるように書くのは避けたほうがいい。
そういうパズル的な事は基本を理解してからでもいいんでないかと。
一文字表示するのを繰り返して、一千文字表示させようっていうなら、 その程度のpush/popは無視してOKだね:b
1000文字だろうが、100000000文字だろうが ポインタ一回渡せば済むだろうに。
ポインタ?
805は「文字列が格納されているメモリの先頭アドレス」と言いたいんだろうね。 でも渡されたアドレスを順番に1文字表示関数でぶんまわすなら無駄なのは同じこと。 1文字表示関数でなく、一度に連続して文字を表示する関数を作れば高速になるし 無駄なpush/popをしたとしても1回だけだから速度の低下は気にならなくなる。
あまり進歩してないですが
先頭アドレスを渡してhello worldは一応出来てるので
1文字ずつ表示するhello worldに挑戦してます。
文字列の指し示す先を参照する方法でつまづいてるのですが
byte ptr [bx]みたいなやり方、間違ってるのでしょうか?
以下のプログラムだと何故か、■みたいな文字が表示されます
情報が少なくて、調べてる時間がほとんどなのですが
どなたかアドバイス願います
;MASM hello worldのhを表示したい
start:
mov bx,offset msg
mov al,byte ptr [bx] ※ココ
push ax
call pchar
mov ah,4ch
int 21h
pchar proc near stdcall ;
>>798 と基本一緒なので省略
msg DB "hello world"
end start
COM作ってるかEXE作ってるか知らないけど 起動時のDSはPSPかなんかに設定してあるんじゃなかったかな。
どもです。 シンプルなので、COMで勉強してます。 microsoft masm programmers guideっていう良サイトみつけたので 試行錯誤の結果解決しました。 変更箇所 start: -> .STARTUP end start -> END なんでうまくいったかについてはまたこれから調査ですが ところでPSPとは何でしょうか? DSとPSPとくれば、携帯ゲーム機ばかりヒットしてしまってorz
BXに入れるのはoffsetと書いてるから、データセグメントレジスタには文字列データの置かれている セグメントのベースアドレスを入れておかないとうまくアクセスできないんじゃ? byte ptr [BX} というアドレッシングは暗黙に 「DSの指すセグメントの[+BX]だけオフセットしたとこ」 ってなるんじゃないの?
TINYモデルならCS = DSである事は保証されてるでしょ?
みなさんありがとうございます。 結論から言えば、まさに811氏の指摘箇所でした。 COMバイナリを比べてみると start:とした場合は開始アドレスが00hからなのに対して .STARTUPの場合は開始アドレスが100hからとなっていました。 そのため、start:の直前にorg 100hを付けても動作が確認出来ました。 また、セグメントレジスタについて確認してみたところ CS=DS=SS=ESとなっていました。 セグメントレジスタ以外にも意識しておくべきアドレスがあるのは 落とし穴ですね
習作ですが、かねてからの目標の一つの
mapサブルーチンを書いてみました
foldはレジスタが足りないのでもっと慣れたら挑戦
;呼び出し
mov ax,lengthof msg
push ax
mov ax,offset msg
push ax
mov ax,offset pchar ;pcharは
>>798 と一緒
push ax
call map
続く
;map定義(pchar定義は略) map proc near stdcall push bp push si mov bp,sp mov ax,word ptr [bp+6] ;function mov bx,word ptr [bp+8] ;array offset mov si,word ptr [bp+10] ;array number mov dl,byte ptr [bx] ;array data mov cx,0 cmp cx,si jg fin @@: push dx call ax inc cx mov bx,word ptr [bp+8] add bx,cx mov dl,byte ptr [bx] cmp cx,si jne @b fin: pop si pop bp ret 6 map endp msg DB "Hello world"
生暖かい目で見守るべきかな。
初めまして。 ところで、 MASMで、「FOR」ではなく「%FOR」と書かれている資料がありますが、 %FOR とはなんなんでしょう?
うわっなつかしい 8086のアセンブラか セグメントが嫌で途中で放り出してしまったな
>>818 予約語を強引にマクロで使っているとか、その辺かもね。
822 :
818 :2009/04/13(月) 18:24:38
>>821 これは、微妙にそれではなくて、
http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/ の下段「MASM Programmer's Guide」の
Chapter 9「Using Macros」の
「Expansion Operator as First Character on a Line」
で説明されている機能を使っているようです。
行頭に%を書くと、ECHO、TITLE、SUBTITLEのようなディレクティブと共に
用いられている「テキスト・マクロ」を展開する、と書かれています。
%FOR もこの目的で使っているようです。
>>822 ☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟
☛Expansion Operator as First Character on a Line
The expansion operator has a different meaning when ...
☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝
824 :
818 :2009/04/13(月) 18:52:10
ちなみに、%FORの例は、
>>822 と同じ章の
「FOR Loops and Variable-Length Parameters」
の例に出てきます。
CTRL+F で%FORを検索してもすぐに見つかると思いますが。
>>824 すみませんでした。
勉強不足だったようです。
☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟
☛FOR Loops and Variable-Length Parameters ☜
With the FOR directive you can iterate through a list of arguments,...
☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝☝
コレだけの人数と技術者がいればOSなんかも作れそうだな
これだけの人数の技術者がいればデスマなんて発生しないよな
実際に作っている人がこっそり混じっている
アセンブラでアッカーマン関数を計算せよという問題が出たのですが、 どうしてもわからないので教えて下さい。 よろしくお願いします。
Cで書いてアセンブラコードを吐き出して、それを読んだほうが早いと思うよ。
main: push %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $0, %eax subl %eax, %esp subl $4, %esp pushl $4 pushl $.LC0 pushl $1 int $0x80 addl $16, %esp leave ret
832 :
デフォルトの名無しさん :2009/04/29(水) 13:33:16
>>831 call writeを使わずに書きたいんだけど下から4行目の割り込みの前後に何を書いたらいいの?
あとage
呼び出し先にreti書いてあるんと違う?
834 :
831 :2009/04/29(水) 16:23:54
.file "test.c" .section .rodata .LC0: .string "tes\n" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $0, %eax subl %eax, %esp subl $4, %esp pushl $4 pushl $.LC0 pushl $1 [ ]←call writeを使わずにシステムコールを使って書き換え [ int$0x80 ] addl $16, %esp leave ret .size main, .-main .ident "GCC: (GNU) 4.2.3 (Ubuntu 4.2.3-2ubuntu7)" .section .note.GNU-stack,"",@progbits まったく分からん。誰かボスケテ
int 80Hがsystem callだと思う。
次のコードの意味ですが src1 < src2 のとき label にジャンプという意味でしょうか? jpoの意味がよくわからないんですが。 fld src1 fld src2 fcom fnstsw ax test ah, 05 jpo label
>>834 push $4
write()のシステムコール番号をpushすりゃいいんだよ。
つーか、普通は%eax, %ebx, %ecx, %edx使って引数渡すが、わざわざ
スタック渡しにしてるんだな。どこの学校の宿題だ?
838 :
837 :2009/04/29(水) 19:06:05
あと、32bitと64bitモードではシステムコール番号が違うから気をつけろ。 write()が4なのは32bitであって、64bit(x86_64)では1だからな。 /usr/include/asm/unistd_{32,64}.hを参照すること。
>>836 最後の2行で何をやろうとしているのか説明してみろ
>>840 ah のビット0とビット2つまり条件コードのC0とC2の内容を見て
1になってるものが奇数のときジャンプするという意味ですかね?
842 :
デフォルトの名無しさん :2009/04/30(木) 18:31:29
静的メンバ変数をg++のx86拡張インラインアセンブリから使うには どうすればいいのでしょうか? オペランドに直接書いても、"m" に指定しても、構文エラーなようで・・・。
>>841 分かってるじゃないか
つまり
>>836 に書いてあることで合ってるということだ
これも宿題か?
844 :
842 :2009/04/30(木) 20:03:20
ようやく自己解決しました。 配列だったのですが、 配列の場合は [0] をつけて1要素で指定しないといけなかったようです。 :"m"(A::a[0]) みたいな感じで。
>>844 当たり前だろ。配列として使いたきゃアドレス渡せって話だ
こんにちは。質問があります。 masm32で mov byte ptr [hoge], 70h は意図した動作(hogeが指す文字列の一文字目に'p'(70h)を代入する)をしないのですが mov esi, hoge / mov byte ptr [esi], 70h とすると意図した動作をします。 何故なのでしょうか? よろしくお願いいたします。
>意図した動作(略)をしない どう動作したか書けよアホ
>>847 何のためのレジスタだよ
メモリオペランドが何を意味するか混同してないか?
もう一度マニュアルを読み直せ
うーん、>847じゃないがまともなMASMのマニュアルがあるなら紹介して欲しいぞ。
>>847 まずはアセンブル可能な完全なコードを提示しろよ。
それじゃhogeがどう定義されてるのかすらわからん。
>>847 少なくともLinux上のGNU assemblerでは、hoge: .ascii "abcd\0"
とデータセクションで定義して movb $'p', hoge(,1) で1文字目の変更が出来た。
AT&T記法のhoge(,1) == Intel記法の[hoge]だから、その書き方で動くはずなんだが。
データをどう定義したか見せてみろよ。
素でm8 to m8だと思っていた/(^o^)\ 単に別のsegment/selectorで読んでいるとか、その辺だろうね。
855 :
847 :2009/05/02(土) 07:46:36
みなさん回答ありがとうございます。 該当部のソースコードは以下のようになっております。 invoke GetDlgItemTextA, hWin, IDC_SPAM, offset spam, 100h invoke foobar, offset spam, offset ham foobar proc piyo :DWORD, hoge :DWORD push esi invoke lstrcpy, hoge, piyo ; これだと駄目 ;mov byte ptr [hoge], 70h ; これならOK mov esi, hoge mov byte ptr [esi], 70h pop esi ret foobar endp
>>855 だからspamとhamはどこでどう定義してんだよ。
データをどう定義したか見せろって言ったのを聞いてないのか?
windowsのapiを使ってるようだけど、環境はWindows3.xということでいいのか?
858 :
847 :2009/05/02(土) 09:11:18
>>856 ごめんなさい。
spamとhamは次のように定義しております。
.data
span db 100h dup(?)
ham db 100h dup(?)
859 :
847 :2009/05/02(土) 09:12:53
XPなのはいいけど、Win32APIを使ってるのかWin16APIなのかを聞いてるんだけど。
861 :
847 :2009/05/02(土) 10:05:28
spam db 100h dup(?) hoge dd offset spam mov byte ptr [hoge], 70h これだとspamの1バイト目ではなくhogeの1バイト目を書き換えている
>>858 もっとコードを単純化してみろよ。Win32 APIもlstrcpy()も呼ばずに、
spamとhamを直接mov byte ptr [ham], 70hとかでいじったら動作するの?
>>862 何が言いたいのかわからん。
lstrcpy()でspamの内容をhamにコピってるんだし、コード的には問題ないだろ。
>hogeが指す文字列 hogeがどこを指しているのか、を確認すれば?
>>863 脊髄反射するなよ。
>foobar proc piyo :DWORD, hoge :DWORD
で piyo と hoge のアドレスはスタックに積まれるわけだ。
>mov byte ptr [hoge], 70h
で byte ptr [hoge] はスタック上のメモリを指していて、それを書き換えている。
けしてスタック上に積まれたアドレスの先を書き換えているわけではない。
>mov esi, hoge
この場合はスタックに積まれた値を読み出しているので正常に稼動する。
Cのコードで説明すれば分かりやすいかな。 void foobar(const char *piyo, char *hoge) { strcpy(hoge, piyo); *((char *) &hoge) = 'p'; //*hoge = 'p'; }
dis assembleで分かる事を...。
>>865 ので解決、と。
868 :
847 :2009/05/02(土) 13:50:35
なるほど。理解出来ました。 皆さんどうもありがとうございました。
short配列の任意の要素番号から8個取り出して、XMMに割り当てる定石は何ですか? SSE2とSSSE3の環境を想定しています。 short ary[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}; // 0, 0, 2, 2, 3, 4, 6, 7, 9 番目を抜き出す xmm1 = {1, 1, 4, 4, 8, 16, 64, 128, 512};
870 :
デフォルトの名無しさん :2009/05/09(土) 01:10:20
すみません、例えばxor命令等のクロック数はどうやって計ればいいですか? どこかでクロック数は公開されてはいませんか?
871 :
デフォルトの名無しさん :2009/05/09(土) 01:17:56
873 :
デフォルトの名無しさん :2009/05/12(火) 00:18:15
変数cは入力値 if(((unsigned char)((c^0x20)-0xA1)<=0x3B)) 入力値0x80-0x9F及び0xA0-0xE0-0xFFを一回の分岐で済むようにする c xor 0x20の0x20の導き方をご教示ください
日本語でおk
875 :
デフォルトの名無しさん :2009/05/12(火) 00:32:53
0xA0^0x80=0x20
878 :
デフォルトの名無しさん :2009/05/12(火) 00:50:52
で、>877でわかったと言うことで良いんだな?
880 :
デフォルトの名無しさん :2009/05/12(火) 01:10:22
>>879 見て解らなかったので、質問しに来ています
if (_ismbclead(c)) 中身は(たぶん)テーブル参照。 アセンブラコードの中で使うにしても どうせ他の用途にも似たような文字判別処理あるんだろうから 自分でテーブルと該当bitを用意しろ。 プログラムの先頭でセットアップするなら「記号のカタマリ」にはならんよ。
(c >= 0x81 && c <= 0x9F) || (c >= 0xE0 && c <= 0xFC)) ここから、t = c ^ 0x20として t >= 0xA1 && t <= 0xDC を見つけるのは勘と言って差し支えないかも。自分もこんなの無理。 ちなみに、負の値をunsigned charに変換すると256 + (基の値)となる。 例えば、(unsigned char)-1 == 256 + (-1)、つまり255。 これを使って、元の判定式では0以上というチェックを省くということをやっている。
883 :
デフォルトの名無しさん :2009/05/12(火) 01:54:55
>>882 連続した部分にくっつけるための0x20は勘ということですか?
>>875 > どこに説明足らずな部分がありますか?
> 入力値0x80-0x9F及び0xA0-0xE0-0xFFを一回の分岐で済むようにする
何回読み直しても「入力値が2つの異なる範囲0x81-0x9F, 0xE0-0xFCに収まるかどうかを
判定する際、1回の分岐で済むようにする」という意味には読めない。
0x9Fと0xA0は連続している。つまり、その記述に対して忠実に考えるなら0x80-0xFFで
ありunsigned charの上限まで連続しているのだから、単純に入力値が0x80以上であるか
どうかを調べるだけで良く、元から分岐が2つ以上発生しない。
故に、日本語でおk。
>>884 なるほど、ご指摘ありがとうございます。
>>885 これ何かの宿題か?今時SJIS判定のコードの説明を聞くなんて。
16進数 : 2進数 0x80 : 0b1000_0000 0xA0 : 0b1010_0000 0xC0 : 0b1100_0000 0xE0 : 0b1110_0000 0x20 : 0b0010_0000 0x20でxorするというのは0b0010_0000の1の部分のビットを反転するというのと同じ意味。 ・1回の分岐で済ませる為には2つの範囲を連続した1つの範囲にすれば良い。 ・0x80を+0x20、0xE0を-0x20すれば2つの範囲は連続する。 ・都合の良いことにどちらも0x20でxorする事でそれを実現できる数である。 見つけ出せるのはきっと勘だろうね。
888 :
デフォルトの名無しさん :2009/05/12(火) 02:33:34
>>887 このレスでようやくわかりました。
感激しました。本当にありがとうございます。
単に16進の扱いがどれだけ頭に馴染んでいるかだろ。 それが理解できない奴は勘ということにしたがるだけ。
16進数というより2進数な。 ビットパターンが頭に馴染んでる奴はオッサンだろ。 こういうテクニックも昔は重宝されたが、今となっては化石だな。
自分の無知を威張る奴ってなんなの
くだらないレスしてる暇あったらアセンブラの話しろや
言い出しっぺの法則と言うのがあってだな
真のオッサーンは8進数のほうが安心できる。 \377 \377 \377 ...
\666 \666 \666
片手使って楽に覚えられるから。 人差し指から小指に向かって8421と数字を振って大きい数から順に指折りして数えればいい。 5は中指と小指を折り曲げるだけ。0b0101とすぐにわかる。
中指と小指だけを折り曲げるのってすごく難しいんだが。
グワシとか、サバラとか
アセンブラやってる人って、なんていうか数学的っていうか、やっぱ 頭のいい連中だわ。理学部出身で天才肌がミエミエだな。
なんこたあー、ない ただの変態だよ
バリバリの文系だけどマシン語ガリガリ書いてた新日プロの日高総帥に謝れ。
世界初のプログラマが文系の女性だったのは周知の事実。
さぞかしグラマーだったんだろうな
ラブレース嬢のことか?
プロ・グラマーとかは誰もが一度は考えてしまうこと
この問題教えてください。 以下のC のコードに対応するMIPS のアセンブリ・コードを書け。 C コード: #define TAB_SIZE 8 int tab[TAB_SIZE]; void main() { int i; for (i = 1; i < TAB_SIZE; i++) { tab[i - 1] = tab[i]; } } • SPIM でのシミュレーションのため、 tab[8] = {8, 9, 10, 11, 12, 13, 14, 15}; としてコードを書け。つまり、データ・セグメントを次のようにせよ。 .data tab: .word 8, 9, 10, 11, 12, 13, 14, 15 • SPIM のDATA セクションが以下のようになることを確認せよ。 [0x10010000] 9 [0x10010004] a [0x10010008] b [0x1001000c] c [0x10010010] d [0x10010014] e [0x10010018] f [0x1001001c] f 1
>>907 これ資料なしで答えられる奴なんて、世界に数人しかいねえんじゃね?
会津大学か?
SPIMでシミュレーションってことは「計算機プログラミングの基礎概念」を 教科書に使ってる所か。
911 :
907 :2009/05/19(火) 21:31:18
一応旧帝です
つか、特定のCPUのニーモニック⇔マシン語コードを空で言えるなんて、無駄もいいとこだな。
「C のコードに対応する」と言うことは、当然最適化もありだよな。 .data tab: .word 9, 10, 11, 12, 13, 14, 15, 15
宮廷レベルでこんな簡単な宿題も解けないのかよ。 これだからゆとりは。
アセンブリ・コードだから、 マシン語じゃないでしょ。
>>907 まずお前が理解している範囲で書いたコードを見せてみろ
こんな簡単なコードも書けないなんてFランク大学としか思えない。 RISCプロセッサのアセンブリコードを書いたのは初めてだが、命令セットを ググるところから始めて30分で書けたぞ。
これは完全にFラン大の馬鹿学生だ・・・
こいつ、名古屋大の学生だな。宮廷も堕ちたものだな。 遊んでばかりいるからこんな簡単な宿題も解けないんだろうが。
俺の初のアセンブラは変な4bit CPUでした
爺さん乙
がっこうのじゅぎょうだから仕方ない。机上プログラミングだよ。
学校行ってたの何十年前だよ。 今時はRISC CPUのシミュレータを使って演習なりするだろ。
いや、ふつーに、x86asmでいいじゃん。
x86_64になってやっと汎用レジスタが増えたが、x86は遺産を引きずりすぎで 汚い。 その点RISCは命令数もアドレッシングモードも少なくて簡単に理解出来る上に レジスタ数が多いから楽だし、ヘネパタとかもMIPSのアセンブリコードを 使ってるから大学等で勉強するのに合ってる。
あぁ、初asmの話。 そりゃ学校でやるなら学校の設備ていいよ。
>>928 また無学な馬鹿が出てきたか。
まともな情報工学/科学の学科であれば必ずアセンブリ言語を使う講義はある。
計算機アーキテクチャを理解する上で重要だし、理論的な方向でレジスタマシンにも
通じる。
16個程度の命令しかない架空のアーキテクチャだよ。 いや、FPGAで実装されてたかな? 自分で勉強したのはx86が最初だ
x86は英語もPerlもC++同様に、汚いが実用的だろ RISCなんて自然言語でいうならエスペラントみたいなもんでしょ。
大学では別に実用性を求めてるわけじゃないからな。どんなアセンブリ言語でも 一つやっておけば大抵はすぐに馴染めるから、何をやるかは重要じゃない。 ただ、アカデミックな文献ではRISCコードが良く使われるから教えるんだろう。
つーかCASL教えろや。何の為に策定したんだよ。 まあ俺はCASLなんか知らないけどさ。
>>933 CASLは専門学校で教えてるんじゃないの?
まともな大学行ってる学生なら試験中に仕様書見るだけで問題解けるぞ。
いや、仕様書だけで理解できるのは「アセンブラというもの」や「CPUアーキテクチャ」を知っている人だけだろ。 レジスタだのアドレッシングだのってものの概念自体を知っているからこそ、「仕様書で充分」となる。 逆に、その辺を最初に理解させるための入門ということなら、まさしく「何でもいいから1つ理解しろ」となるわけだが。
>>917 それはFランを馬鹿にしすぎ。
このくらいのことが出来ないのはFランでもやる気のない最底辺クラスの人間くらいだよ。
>>935 COMET/CASLの仕様見たことあるか?
まあレジスタにデータを読み込んで計算する、という概念は知っていた方がいいが、
アドレッシングなんて知らなくても何とかなるレベルだぞ。
>>936 Fラン大なんて中学レベルの数学も怪しいんだろ?
そんな奴にアセンブリ言語を理解出来るはずないだろ。
>>929 参考書を提示するだけにしておき、教えはしないっていう程度のモノ。
わざわざ、viやらWordの使い方を教えたりしないのと、同じこと。
>>937 ピンキリ。そういう奴もいるけどね。
リファレンス見ながらなら、小学生だってアセンブリ言語を使える。
使いこなせる、とは言わないけど。
>>907 SPIMで動くかどうかはしらないけど、多分こんな感じ?
.data
tab: .word 8, 9, 10, 11, 12, 13, 14, 15
.text
.global _main
.ent _main
_main:
li $t0, 1
li $t1, 1
li $t2, 8
L1:
beq $t0, $t2, L2
lw $t3, tab(t0)
sub $t4, $t0, $t1
sw $t3, tab(t4)
add $t0, $t0, $t1
b L1
L2:
jr $ra
.end _main
>>938 お前本当に馬鹿だな。アセンブリ言語を教えるための講義じゃないぞ。
講義の中で「使う」から解説するだけだろうが。
>>939 お前がFラン大擁護者なのは分かった。
Fランに入る奴は中学レベルの知識も身につけられない程努力が足りないからだ。
そんな奴がCPUのマニュアル読んでアセンブリ言語を覚える努力をするとでも思うか?
ちなみにそれじゃ動かないぞ。MIPSアーキテクチャでワードが何バイトか分かって
いないようだな。つーか宿題お答えスレじゃないんだから教えるなよ。
ああいう馬鹿には退学してもらう方が税金の節約になって良い。
>>940 黙ってりゃそのまま提出して痛い目にあってくれたかもしれないのに・・・。
wordが32bit幅なのは知ってるし、このままじゃ動かないことも承知してるよ。
>>940 スレ違いな話題だから避けようかと思ったけど、これも言っておこうかなぁ。
> Fランに入る奴は中学レベルの知識も身につけられない程努力が足りないからだ。
> そんな奴がCPUのマニュアル読んでアセンブリ言語を覚える努力をするとでも思うか?
実際に見てきた範囲だと2:8くらいかな。努力する子が2、努力しない子が8。
世の中、おたくが思ってるほど単純には出来てないよ。もちろんFランもね。
国立蹴ってFラン入る酔狂な奴、資格取得目的の社会人、そういうので無くても、
比較的マシな奴は割とザラにいる。Fランに入る奴は中学レベルの知識も身につけ
られない、努力できないなんてのは、おたくの勝手な思い込みでしかない。
まあ、そういうのも沢山いるけどね。ただの落ちこぼれから、現役暴走族レベルまで
色々と。
あと、おたくもインテリゲンチャの端くれなら、あまり知らない事を単純化して
決めつけてかかったり、すぐに人を罵倒したりするのは、よした方が良いと思うよ。
粗野で卑しい程度の低い人間に見られるのは嫌でしょ?
いつもこの流れ
CASLはワードアドレッシング。 わざわざCASLを選ぶ理由がなけれ選ばないな。俺が担当者なら。
FPGAとかCPLDとかで独自アーキティク茶のCPU作る実習とかある学校ってないの?
>>947 テーマで選択すれば、って大学は結構あると思う。
東大のISはプロセッサだけじゃなくてそれ用の処理系を作ってレイトレアプリを
やるところまで全員がやる。
>>944 粘着乙
>>948 理学系の情報科学科でもCPU作るんだよな。工学系だと大抵やるはずだけど。
処理系って、作ったCPU上でコンパイラまで一人で作成するってこと?
それってどれだけ時間が掛かるんだよ。
> 処理系って、作ったCPU上でコンパイラまで一人で作成するってこと? チームで分担してた、はず。
>>950 チームプロジェクトなら通年じゃなくても行けるか。
ただデバッグ地獄になりそうだな。CPUのデバッグが完了しなかったら
チーム全員単位落とすのかな。
>>951 いやバーチャルマシン作ってデバッグとか
先輩の残した遺産もあるしね
工学部だがCPUなんて作らなかった。 論理回路なら作った。
ダイオードは作ったな。 手作業でウェハ磨いたりドライヤーやホットプレート駆使 したり作業の一部はほとんど家庭料理だった。
1年ありゃあ、CPU作ってコンパイラ作ってその上でアプリまで動かせるだろ。 むしろアプリ先にありきでCPUのアーキ考えないとな。
最近ちょいとアセンブラに興味を持ち始めて、 VC++ 2008 のデバッグモードにて、空の関数 void Test() { } をビルドして逆アセしてみたら、以下のようになりました。 ?Test@@YAXXZ (void __cdecl Test(void)): 00000000: 55 push ebp 00000001: 8B EC mov ebp,esp 00000003: 81 EC C0 00 00 00 sub esp,0C0h 00000009: 53 push ebx 0000000A: 56 push esi 0000000B: 57 push edi 0000000C: 8D BD 40 FF FF FF lea edi,[ebp+FFFFFF40h] 00000012: B9 30 00 00 00 mov ecx,30h 00000017: B8 CC CC CC CC mov eax,0CCCCCCCCh 0000001C: F3 AB rep stos dword ptr es:[edi] 0000001E: 5F pop edi 0000001F: 5E pop esi 00000020: 5B pop ebx 00000021: 8B E5 mov esp,ebp 00000023: 5D pop ebp 00000024: C3 ret ↓続く
↑の続き このアセンブリコードにて、3行目の sub esp,0C0h で、スタックポインタを192byteデクリメントした後に 0xCC で埋めてますが、 なぜ192byteを確保しているのか、理屈がよく分かりません。 また、上記の空関数に int の変数宣言を1つ追加するたびに、 スタックの確保サイズが、intのサイズ(4byte) ではなく、12byte ずつ増えるのですが、 なぜ 12byte なのか、これの理屈もよく分からず気になりました。 分かる方いらっしゃいましたら、よろしくお願いします。
デバッグのために追加されてる、と考えればいいじゃないか。
リリースモードでコンパイルしてdiff取ってみろよ
フフフフフフフフフ
>>957 ローカル変数のバッファオーバーラン検出用じゃないの?
>>956 CodeGear(旧Borland)のCodeGuaedでも似たような手法を使っている
ダミーデータを埋め込み、不正な書きこみ、例えば配列の添え字外の
書きこみなどを検出している
時々お節介な事もしてくれるが、ポインタ関係で悩ましいバグが取れない
時は重宝してるよ
>>961 >>962 ありがとうございます。
何か用途があるのかと思って調べてたので、スッキリしました。
964 :
デフォルトの名無しさん :2009/05/26(火) 21:28:27
IDAProで、 int main(void) { puts("は?ははは"); return0; } を逆アセンブったところ Ollydbgでは s=は?ははは IDAProでは db '0h' db '0h' みたいに続くのですが、これをs=は?ははは のように見れませんか?
>>964 datarescueに問い合わせたら?
966 :
デフォルトの名無しさん :2009/05/30(土) 00:09:54
KUE-CHIP2で浮動少数点数同士の乗算をせよという課題が出たんですがさっぱりわかりません 親切な方いましたらよろしくお願いします
授業で手取り足取り教えてくれてるんだから、真面目に出て話し聞いてりゃいいじゃない。 資料だってあるんだから、見ながらやれば猿でもできる。
968 :
デフォルトの名無しさん :2009/06/04(木) 05:08:14
IDA-PROの日本語化パッチを公開したら皆さんは喜んでくれますか?
あんまり。
971 :
デフォルトの名無しさん :2009/06/12(金) 00:30:29
レジスタの中身をクリアする場合に、同一作者のソースの中でも xor ax, ax xor dx, dx xor cx, cx とするいっぽう、別のルーチンでは mov dh, 0 mov si, 0 となっている実例がありました。他方、別の作者ですと、統一されていて、 レジスタクリアは、16bit一括で xor di, di xor cx, cx としている方もいました。 どちらの方も90年〜93年くらい、ちょうどDOS円熟時代のウイルス作者なのですが、 ご本人がコメントを詳細に付けておられるんで、可読性を考えてmov ch, 0としたとは あまり考えられないのですが…(個人的な見解ですが、アセンブラの勉強に、太古のウイルスの ソースコードを追うのは大変有意義であると考えます)。 この件は、もしかしたらマシンサイクル?と関係しているのかなと思っているのですが、 こういった実行サイクル・クロックの有利不利に関する情報のあるWebサイト・書籍がありましたら ご教示ください。個人的には、上記1番目の作者のものを改変するのであれば、 xor dh, dh xor si, si などとしたいところですが。昔、xor レジスタ、レジスタのほうがmov レジスタ、0よりも 実行サイクルが短い、みたいな記述をよくアセンブラ解説系のサイトで見かけたものですから…。 実機実行環境は、80386SX-16MHz/387/6MB RAM、MMX Pentium 200MHz/64MB RAMくらいです。
そりゃ8bit時代の話やね。いまどき1バイトや1クロック稼いでも意味無いしな。 あとRISCマシンならどっちも同じ命令とかよくある。
>>971 ふつーに考えて、可読性を考慮しているだけ。
movの方は引数、xorは単なる0clearだろうね。
もしかしたら、だけど、フラグを変化させないために、xorじゃなくてmovに してるかもしれないけど。
975 :
971 :2009/06/12(金) 09:47:21
>>972-974 回答ありがとうございます。
なるほどー、いろんな見方があるんですね。
>>972 たしかに現代の計算機ではたかが1クロック稼いだところでなんなの?って感じですけど、
コトは20年前の環境ですんで、悪しからず。開発マシンが386SXで、実行マシンが
286とか初代Pentium 133MHzとかなので。Pentiumだと、パイプライン?だかの影響で、
従前の8086的なアセンブラの記述・手法が逆に祟ってしまうことがある、とどこかで
読んだ記憶があります(はじめての〜80486だったか?)。
>>973 この場合の可読性ってのは、自分で後でパっとみて判るように、ってことでしょうかね。
コメントがびっしり拙い英文で書いてありますが(ネイティヴではない)、ゼロクリアに関しての
言及はなかったですから。
>>974 そうですか!確かに、mov命令ならフラグ変化をさせずに、という「利点」がありますね。
ウイルス作者もなかなかやりますねw あの当事の作者たちは、ある種の強者だったんでしょうか。
そんなソースを一体どこから?
直前にフラグを変化させる命令があって、その結果で分岐したいけど、 先にどうしてもレジスタをクリアしないといけないときぐらいしか利点が無い。
978 :
971 :2009/06/12(金) 11:15:35
>>976 直リンは避けますが、Googleで"Virus Source Code Database"でぐぐれば、
ちょうど89年〜93年ころの、16Bitアセンブリソースコードが山ほどでてきますよ。
ほとんどは、オリジナル作者の解説がついてますんで、ルーチンを追うのも
さほど苦労はない感じです。COM/EXE Infector型とか、そういうのが主流でした。
あと、ディレクトリエントリぶっ壊したり、COMMAND.COMを書き換えたり、
ブートディスクのすべてのサブディレクトリを逐次探索して、そこのCOM/EXEに
ことごとく自分のウイルスヘッダ?をぶち込んで機能不全にし、撒き散らしたりとか、ですか。
でも、昨今のウイルスに比べれば、頑張って作っている様子はわかりますよ(苦笑
>>977 なるほど。
パッチ作るときに使ったな
xor以外にも、subでも同じゼロクリアできるな。 好みの問題だけどな。 あ、キャリーフラグが面倒かw 8086系以外のCPU使ってるとその辺は色々あっておもしろいぞw ゼロクリア専用の命令があるのとかな。
x86でもfpuにはfld0とかfld1とかあって便利。
向こうの住人の了解が得られれば、いいと思います。
RISC系だと常に値が0のレジスタがあったりして mov %r0, %rxx みたいに ゼロクリアしたりするな。
0レジスタ、実はHD6309にあったりする。
>>971 ウィルス検出パターンに引っかからないため、ってのはないかな?
987 :
デフォルトの名無しさん :2009/06/14(日) 01:25:56
ハッキング非公式マニュアルという書籍に載っているアセンブラは、
なんでそこで切る
検索すると「ハッキング非公式ガイド」という本はあるようだが
990 :
デフォルトの名無しさん :2009/06/14(日) 14:19:20
それです。 アセンブラを学ぶのに参考になりやすかい?
基礎も学ばずに応用をやろうだなんて…
ハッキングから学ぶのは非常ーに大変です
なんで厨はハッキングから入ろうとするの?
厨だから。
995 :
デフォルトの名無しさん :2009/06/15(月) 18:08:45
Vistaでdebugコマンドを打った後にqを打って16bitmodeにする作業を .batによって自動化させるにはどのように記述すればいいですか?
q.txt q [EOF] debug < q.txt
q<改行> というファイル(q.txtとする)を作って、 バッチファイルでは、 debug < q.txt とする。
q('A`)p
999 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
asm
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。