LD GR3,GR1 ;GR3にGR1の数字を入れる。
AND GR3,=#000F ;数字を数値に変換

というアセンブラのプログラムがあったのですが、なぜGR3と16進数#000Fの論理積をとることで数字を数値に変換できるのでしょうか。

それと、ここでいう数字、数値の違いとは、数字の1はコンピュータ上では
49という数値に変換される(アスキー文字)という認識でよろしいでしょうか。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

2進数で表したときの下4桁だけが残ることになるからです。



アスキーコードでは、数字の「1」は、10進で49、16進で31です。
16進の31を2進数に直すと、0011 0001です。
これと16進のOF、つまり2進の0000 1111と論理積をとると、0000 0001となり、数値の1になります。
    • good
    • 0
この回答へのお礼

ご解答ありがとうございました。

お礼日時:2009/05/27 21:05

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QX86アセンブラで 16進数を10進数のASCIIコードに変換する方法

X86アセンブラで16進数から10進数のASCIIコードに変換する方法を模索しております。

例:  0x64(100d)
期待値:0x31 0x30 0x30 ("1","0","0"の3ByteのASCIIデータ)

といった内容になります。
論理演算等で求める手法がございましたら、ご教授頂ければ幸いです。

Aベストアンサー

テーブルを用意すればコード自体は簡単にできますが、その他の解です。

hexに16進数、asciiに変換後のASCIIコードの10進数を格納するとします。

hex db ?
ascii db 3 dup (?)

コードは以下になります。

moval,hex
aam
oral,30h
movascii+2,al

moval,ah
aam
orax,3030h
movascii,ah
movascii+1,al

QCASLII:文字列→数字への変換の原理

CASLIIにおいて
文字列を数字へ変換する場合、000FでAND演算をしますよね?この方法で変換が行なえることはわかるのですが、なぜ000FでAND演算をすると変換されるのか、その原理が分かりません。
ご教授のほどお願い致します。

Aベストアンサー

数字の文字列表現は、16進表記では
0が0x30、1が0x31...9が0x39
となりますので、上位4ビットをクリアして、下位4ビットを維持すれば数値に変わります。

QCASLIIの数値データ入出力

入出力のときはJISの文字コード表の値が使われ、それ以外の計算などにおいては通常の2進数が使われるとのことですが、その変換はどのように行うのでしょうか。

テキストには「1~9の文字には16進数の(0030)を減算」「A~Fの文字には(0037)を減算」と書いてあります。

例えば
’5’は内部コードでは(0035)、
16進数の数値では(0005)
数値と文字コードの差は16進数で(0030)

というのは理解できます。

ただアルファベットになると理解できません。

例えば
’A’は内部コードで(0041)
16進数の数値では(000A)
数値と文字コードの差は16進数で(0037)

なぜここで(0037)になるのでしょうか・・。
(0041)を(0037)で減算し、(000A)になるまでの過程を教えてください。

Aベストアンサー

文字→数値変換ですね。
説明が面倒ですが、内容はごく単純です。頭をやわらかくして。

0 = 文字コード(0030) - (0030)
1 = 文字コード(0031) - (0030)
2 = 文字コード(0032) - (0030)
5 = 文字コード(0035) - (0030)
9 = 文字コード(0039) - (0030)

ここで、A = 文字コード - 0030 と同様にやりたいところですが、駄目です。
文字コード表を見ればわかる通り、1~9の文字コードとA~Fの文字コードは離れているので。(連続値として変換できない)
A~Fは基準点になる0030という数値が変わってきます。

A = 文字コード(0041) - (0041) + (000A)
B = 文字コード(0042) - (0041) + (000A)
F = 文字コード(0046) - (0041) + (000A)

この、-0041+000A を計算してまとめると、-0037

A = 文字コード(0041) - (0037)

となります。

こんな手法プログラム作成時に本当にやるのか!と言われそうですが、
使う人は使いますし、知っておいて損はないです。

文字→数値変換ですね。
説明が面倒ですが、内容はごく単純です。頭をやわらかくして。

0 = 文字コード(0030) - (0030)
1 = 文字コード(0031) - (0030)
2 = 文字コード(0032) - (0030)
5 = 文字コード(0035) - (0030)
9 = 文字コード(0039) - (0030)

ここで、A = 文字コード - 0030 と同様にやりたいところですが、駄目です。
文字コード表を見ればわかる通り、1~9の文字コードとA~Fの文字コードは離れているので。(連続値として変換できない)
A~Fは基準点になる0030という数値が変わってきます。...続きを読む

Qアセンブラで割り算

アセンブラ記述で割り算を実現させたいのですがよくわかりません。
下記条件でどのように実現すればよいでしょうか。
・8ビット÷4ビット
・命令セットは
 LDL, LDH, MOV, ADD, SUB, SRA, SR, SL,
AND, OR, JE, JMP, CMP, LD, ST, HLT
・レジスタは16ビット
・レジスタは8個


です。
「被除数の上位4ビットと除数を比較して商を求めて、余りに被除数の次ビットを連接する」
の繰り返しでできると思っているのですが、アセンブラ表記がわかりません。
よろしくお願いします。

Aベストアンサー

なんとなくニーモニックが似ているのでZ80の割り算の例。
http://ldlabo.hishaku.com/NO24/hontai.htm#15

Q機械語からアセンブリ言語への変換の仕方を教えてください

CASLIIを学んでいるのですが、命令後の表(画像)を使って
プログラムの一部
ADDA GR1,GR1
を手動で機械語 (16進)に変換すると、 2411 になるようなのですが、どのように変換するのでしょうか?
ネットで調べてみたのですが”機械語の命令(変換)表で命令と語数を確認しながら,アセンブリ言語の表記にします。”と省略されていて詳しく解説してあるページが見つからなかったので、教えていただけませんか?
ーーーーーーー
機械語の命令(変換)表
http://www.jitec.jp/1_13download/hani20061107.pdf
(32 ページに機械語とアセンブリ言語の命令の対応表があります)

Aベストアンサー

やることは (書くだけなら) 簡単です.
まず
ADDA GR1,GR1
という命令がどの形式に当てはまるかというと, GR1 と GR1 はどちらも (と言っても同じものだが) レジスタなので
ADDA r1,r2
に当てはまります. これは変換表を見ると OP が 24 であり, その後に r1, r2 のそれぞれのレジスタを表す数値を並べればいいということになります. ここではどこにも書かれていませんが, レジスタ GR1 を指定するためには「1」という値を使うことになります. ですから
24 (ADDA r1,r2 の OPコード) 1 (今は r1 として GR1 を使っている) 1 (今は r2 として GR1 を使っている)
から 2411 という機械語が生成されます.
この辺の手順は実際のプロセッサでも同じです. ただ「どの形式に当てはまるのか」が分かりにくくなったり, 「レジスタを指定する値の決め方」がトリッキーになったりするだけ.

Qscanf("%s", buf);でスペースを含んだ文字

コンソールプログラムで
scanf("%s", buf);
を使用してユーザに入力された文字によって処理を行いたいのですが、このままではスペースを含む文字列がスペースの手前で切られてしまいます。
C:\Program Filesなどを入力可能にさせたい場合にはどのようにするのがベターですか?

Aベストアンサー

お任せください!
そもそもscanfを使うというのはお勧めでは
ありません。scanfは文字+改行文字が入力
されないと完了しないためです。
が、それは良しとしましょう。
scanfの書式ですが、

int n = scanf("%[^\r\n]",buf);

という便利な書式があります。
perlでもおなじみの書式ですね。
上記の山文字"^"より前が読み込ませたい文字の集まりで、ハイフン指定が出来ます。
"^"より後ろが読込みを停止させたい文字の集まりです。上記の指定は復帰改行以外の文字が現れるまで読み込みます、という書式です。
下記のような指定も出来ます。

int n = scanf("%[a-zA-Z0-9\\: \t^\r\n]",buf);

なお、戻り値は読み込んだ項目数ですので、
if(n >= 1)
{
}
で判断できますね。

Q戻り値の意味がわかりません…

戻り値とはどういう値なのか簡単な例文で教えて頂けますか?

Aベストアンサー

バカくさいかもしれませんが簡単な例えをだしてみます。
2人の子供がいて、名前をそれぞれ太郎・花子にしましょう。この2人の子にある役割を決めます。
・花子は飴をもらうと、それをチョコにする役割。(できるかは別として)
・太郎は花子を呼んで飴をあげる役割。

さてこの例では太郎の飴が引数(ひきすう)になり
花子のチョコが戻り値になります。

このイメージを元に次の文を読んでみてください。

「プログラム中の関数やサブルーチンが処理を終了し
呼び出し元に処理の結果として返す値。」

これが戻り値の正しい定義です。
そのほかにはNo1さんのような役割指すときも、それを「戻り値」と呼んだりします。

Qmain関数終了時のreturnの意味は?

質問の題名通り、main関数終了時のreturnの意味が知りたいです。いつもは参考書に書いてある通り、return 0とやっていたのですが、参考書のサンプルプログラムでreturn 1というのがでてきた為、少し混乱しました。
参考書に説明が載っていないのでmain関数内でのreturnの意味をご教授願いたいです。よろしくお願いいたします。

Aベストアンサー

# 4です。

まず、0を返そうが、1を返そうが、そのプログラム自体の内部的な動作は通常変わりません。
戻り値で動作が変わる可能性があるのは「そのプログラムを呼び出したプログラム側」です。

例えば、make から呼び出された場合にそのプログラムが0以外が返したら、makeは「そのプログラムは失敗した」と考えて、処理を中断したりします。(続けて欲しいなら「成功」を返す、こういうために使います)
コマンドラインからあなたが手で入力したのなら、何も起きないかもしれません。

1を伝えられたOSが何をするかは環境(OS)によります。
gccは、Windows版もLinux版も各UNIX版もあるようなコンパイラですから、その版によって違う可能性があります。
ちなみに、手元の Minimalist GNU for Windows では 1 は EXIT_FAILURE でした=つまり前述のような失敗。
別のOS上のgccでは別の値にポートされている可能性も否定はできません。

C言語が保証しているのは、EXIT_SUCCESSを返したとき、その環境では成功と判断してくれるだろう値を返すことと、EXIT_FAILUREのときは失敗と判断してくれるだろう値を返すことだけです。
0は通常EXIT_SUCCESSですが、1はEXIT_FAILURE とは限りません(現実的には 0 と 1 が大半だと思いますが、EXIT_FAILUREが-1とかでも違反ではないです)。
但し、実際に判断できるかはOSにもよりますし、呼び出したプロセスがどう判断するかにもよります。

なお、Windows や Linux, その他私の知っている UNIX では、1を返されたからといって必ず何かが行われるということはありません。
前述のように、別のプログラム等から呼び出された場合に、そのプログラムが失敗と判断して何か処理を行う可能性はありますが、これらはあくまで呼び出し元のプログラムによります。
ITRON等の組込みOSでは、main が値を返す事は通常ありません。

憶測ですが、参考書のサンプルで return 1;となっているのは、例えば argv が求めているものと違うとか、fopen に失敗したとか、そういうケースではありませんか。
そういう異常処理が発生した場合に、もしも呼び出したプログラムがいたらそれを伝えられるように、EXIT_SUCCESS (0)以外の値を返すのは慣習です。
具体的にどんな値を返すかは、プログラムの設計次第になってしまいますが、1や-1を返したり、失敗原因ごとに決めた値を返したりします。
汎用性を重視するならEXIT_FAILURE等もありますが、知名度もやや低いですし、0以外なら何でもいいという認識の人も多いように思いますので、サンプルは単に1を返しているのではないかと。

# 4です。

まず、0を返そうが、1を返そうが、そのプログラム自体の内部的な動作は通常変わりません。
戻り値で動作が変わる可能性があるのは「そのプログラムを呼び出したプログラム側」です。

例えば、make から呼び出された場合にそのプログラムが0以外が返したら、makeは「そのプログラムは失敗した」と考えて、処理を中断したりします。(続けて欲しいなら「成功」を返す、こういうために使います)
コマンドラインからあなたが手で入力したのなら、何も起きないかもしれません。

1を伝えられたOSが...続きを読む

Q構造体の初期化方法について

こんばんわ。
何度も申し訳ありません。

VC++.NET 2003を用いてコンソールプログラミングを行っています。前回この掲示板を利用して複数回実行するプログラムを作成し、そこに構造体を用いたプログラムを作成しました。以下に概要を示します。

グローバルで構造体を宣言しているため、複数回実行を行うプログラムでは前回の値が格納されたままであると思い、毎回実行時に構造体の初期化を行いたいと思っています。

そこで、以下に示します構造体の初期化はどのように記述すればよいのでしょうか?0で初期化したいと思っています。

よろしくお願い致します。

#define MAX 2000
//グローバル
struct tag{
int Npkt;
int gettime;
int rPkt;
int lossPkt;
}rdata[MAX];

main(){
  //for文で複数回実行処理
  for(i=0;i<=5;i++){
  //ここで構造体の初期化を記述する
//例として、5回プログラムを実行する
  }
}

こんばんわ。
何度も申し訳ありません。

VC++.NET 2003を用いてコンソールプログラミングを行っています。前回この掲示板を利用して複数回実行するプログラムを作成し、そこに構造体を用いたプログラムを作成しました。以下に概要を示します。

グローバルで構造体を宣言しているため、複数回実行を行うプログラムでは前回の値が格納されたままであると思い、毎回実行時に構造体の初期化を行いたいと思っています。

そこで、以下に示します構造体の初期化はどのように記述すればよいのでしょうか?0で初...続きを読む

Aベストアンサー

★まとめ
・既に『memset』関数や、『ZeroMemory』関数の回答があるので構造体の全体、1部の
 初期化の記述例を紹介します。
・それと『#include <memory.h>』を記述しないとメモリ関係の関数が利用できません。
 『ZeroMemory』関数の場合は『#include <windows.h>』があればそのまま利用できます。

●構造体全体を初期化
ZeroMemory( rdata, sizeof(rdata) ); または、
memset( rdata, 0, sizeof(rdata) ); です。

●構造体一部を初期化
ZeroMemory( &rdata[i], sizeof(struct tag) ); または、
memset( &rdata[i], 0, sizeof(struct tag) ); です。
※rdata[i]の1データだけ初期化します。

余談:
・『ZeroMemory』関数は Win32 API と分類されていますが、実体は『memset』関数に
 『#define』されているだけです。でも、戻り値を『VOID』型にキャストされているので
 『memset』関数のリターン値を取得できません。→第一引数のアドレスが『memset』関数
 ではリターンします。
・以上。おわり。

参考URL:http://taka.no32.tk/tips/Win32/ZeroMemory.html

★まとめ
・既に『memset』関数や、『ZeroMemory』関数の回答があるので構造体の全体、1部の
 初期化の記述例を紹介します。
・それと『#include <memory.h>』を記述しないとメモリ関係の関数が利用できません。
 『ZeroMemory』関数の場合は『#include <windows.h>』があればそのまま利用できます。

●構造体全体を初期化
ZeroMemory( rdata, sizeof(rdata) ); または、
memset( rdata, 0, sizeof(rdata) ); です。

●構造体一部を初期化
ZeroMemory( &rdata[i], sizeof(struct tag) ); または、
m...続きを読む

QPIC 文字 を 数値に 変換

アセンブラ言語(PIC)で、シリアルで受信した文字列数値を数値に変換したいのですが、どなたかプログラムを教えてくださいませんか?

Aベストアンサー

プログラムは教えませんが、アルゴリズムなら。

送信されてくるデータが、上位から送られてくるものとします。
本当は16進数が簡単ですが、10進数で話を進めます。

(1)
データを保存するメモリ(以下、保存メモリ)を0クリアしておく。

(2)
保存メモリを10倍する。(16進数ならここで16倍する→4ビット左シフトする。)

(3)
終端コードを受信したら、終了。

(4)
1文字受信したらASCII-数値変換し、保存メモリに加算する。

(5)
制御を(2)に移す。

以上です。

※ ASCII-数値変換は、受信データから'0'を引けばいいです。
※ 10倍は、8倍と2倍を加算すればいいです。
※ 終端コードは、C言語との互換性を考慮してNULL(=0x00)にしておくといいです。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報