Skip to content

Instantly share code, notes, and snippets.

@lpproj
Created September 18, 2019 12:39
Show Gist options
  • Save lpproj/3097703e1a61f7be6fb564c3a3262fec to your computer and use it in GitHub Desktop.
Save lpproj/3097703e1a61f7be6fb564c3a3262fec to your computer and use it in GitHub Desktop.

いまさら人に聞けないx86アセンブラの書き方(読み方)―記数法

MASMやNASMなどの、16~32ビットx86アセンブラでよく使われる数の書き方を念のため書いてみる。 (これいる?)

10進数(decimal)、2進数(binary)、16進数(hexadecimal)、8進数(octal)

10進数

日常で使う数の書き方。ふつうだな!

	mov	ax, 1234		; axレジスタに数値1234を代入

注意点として、数値の最初に 0 を書いておくと8進数とみなすものがある。 アセンブラだとUnix互換のas(gas)が代表例。 (アセンブラに限らず、C++やJavaScriptなどもそうなので時々はまる)

.section .text
.code16

	mov	1234, %ax		/* axレジスタに数値1234を代入 */
	mov	01234, %bx		/* bxレジスタに数値668(10進数)を代入 */

MASMやNASMでは、数値列の最後尾に d を書くことで10進数を明示的に表現できる。

	mov	ax, 1234d		; axレジスタに数値1234(10進数)を代入

NASMでは先頭に 0d を置く書法も有効。 使うメリットはない、と思う…。

	mov	ax, 0d1234	; axレジスタに数値1234(10進数)を代入

ちなみに、なんで10進数であることを明示する必要があるのかというと、MASMではデフォルトの数値表現を10進数以外にもできるため(後述)。 くわばらくわばら…。

2進数

1と0だけを使った数値の表記。 すごくデジタルだね!

MASMやNASMでは、1と0だけで書かれた数値列の最後尾に b を書くと2進数とみなされる。

	mov	al, 110101b		; alレジスタに数値53(10進数)を代入

NASMではC++、JavaScript、Pythonと同じような、先頭に 0b を置く書法も有効。

	mov	al, 0b110101	; alレジスタに数値53(10進数)を代入

16進数

ひとつの桁で(10進数でいうところの)0から15までの数を表す。
10以上の数のときはアルファベットを使う。16進数の場合はAからFまでとなる。

4桁の2進数(0000~1111)をちょうど1桁の16進数で表現できる。 たいていのコンピュータは4で割り切れるビット数(8、16、32、64ビット)をデータ処理の単位にしているので、この表記にすると内部データを無駄なく表現できて便利。

MASMやNASMでは数値列の最後尾に h を書くと16進数とみなされる。

	mov	ax, 1234h		; axレジスタに数値4660(10進数)を代入

数値の先頭が0~9の範囲でない場合は、先頭に 0 をつける。 つけないと数値ではなくシンボル名と判断され、たいていの場合エラーとなる(ならない場合は逆に始末が悪い。定義済みのシンボルやマクロが想定外の場所で使われていることを意味するので)。

	mov	ax, deadh		; だいたいエラーになる
	mov	ax, 0deadh		; axレジスタに57005(10進数)を代入

NASMではC++、JavaScript、Pythonと同じような、先頭に 0x を置く書法も有効。

	mov	ax, 0xbeef		; axレジスタに数値48479(10進数)を代入

8進数

ひとつの桁で(10進数でいうところの)0から7までの数を表す。

3桁の2進数(000~111)をちょうど1桁の8進数で表現できる。 10進数よりは内部データの表現に都合がよく、16進数と違って日常的な数値だけで表現できるというのがメリットかもしれない(逆にまぎらわしいともいえる)。

MASMやNASMでは数値列の最後尾に q を書くと8進数とみなされる。

	mov	ax, 1234q		; axレジスタに数値668(10進数)を代入

NASMではC++、JavaScript、Pythonと同じように先頭に 0o を置く書法も有効。 (他の言語と異なり、NASMはOqも可)

	mov	ax, 0o1234		; axレジスタに数値668(10進数)を代入

MASMの .RADIX ディレクティブ

MASMは .RADIX ディレクティブで、デフォルトの記数法を10進数以外にすることができる。 はっきりいって罠でしかない。

	.RADIX 16
	mov	ax, 1234		; axレジスタに数値4660(10進数)を代入
	.RADIX 8
	mov	bx, 1234		; bxレジスタに数値668(10進数)を代入
	mov	cx, 1234d		; cxレジスタに数値1234を代入

ちなみに .RADIX で有効な値は2~16まで。 頭の体操にいいかもね!(ほんとに罠でしかない)

	.RADIX 2
	mov	ax, 1000		; 8(10進数)
	.RADIX 3
	mov	ax, 1000		; 27(10進数)
	.RADIX 4
	mov	ax, 1000		; 64(10進数)
	.RADIX 5
	mov	ax, 1000		; 125(10進数)
	.RADIX 6
	mov	ax, 1000		; 216(10進数)
	.RADIX 7
	mov	ax, 1000		; 343(10進数)
	.RADIX 8
	mov	ax, 1000		; 512(10進数)
	.RADIX 9
	mov	ax, 1000		; 729(10進数)
	.RADIX 10
	mov	ax, 1000		; 1000(10進数)
	.RADIX 11
	mov	ax, 1000		; 1331(10進数)
	.RADIX 12
	mov	ax, 1000		; 1728(10進数)
	.RADIX 13
	mov	ax, 1000		; 2197(10進数)
	.RADIX 14
	mov	ax, 1000		; 2744(10進数)
	.RADIX 15
	mov	ax, 1000		; 3375(10進数)
	.RADIX 16
	mov	ax, 1000		; 4096(10進数)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment