x86 汎用命令 - ModR/M の解説
ModR/Mについては前もちょっと記事を書いたけど、まだちょっと中途半端だったのでもう一度まとめます。
nantonaku-shiawase.hatenablog.com
ModR/Mの実際の例
例えば以下のような命令がある、 /r の意図がみなさんわからないのではないでしょうか?
; IMUL r32, imm32 0x69 /r iw
また、次のような命令、 /7 の意図がみなさんわからないのではないでしょうか?
; CMP r/m8, imm8 0x80 /7 ib
ModR/Mの構造
全体の概要についてはこのページをみたほうがよい
また、このページも役立つ
'''/r'''および'''/7'''の意味
解説を Assembly Programming on x86-64 Linux (06) から引用する
この記事で注目している項目を赤字で表現。
記法 | 解説 |
---|---|
/0 - /7 | ModR/M バイト の reg フィールドの 0 から 7 の数字はオペコードの拡張用に使われる。r/m フィールドだけをオペランドに使用する。 |
/r | 命令には ModR/M バイトが続き、レジスタオペランドと r/m オペランドの両方を使う。 |
cb、cw、cd、cp, co, ct | オペコードの後に 1 バイト(cb)、2 バイト(cw)、4 バイト(cd)、6 バイト(cp)、 8 バイト(co)または 10 バイト(ct)が続く。 |
ib, iw, id, io | オペコード、ModM/R バイト、または SIB の後に続く 1 バイト(ib)、2 バイト(iw)、4 バイト(id)または 8 バイト(io)の定数(即値)。 |
+rb, +rw, +rd, +ro | + の左側のオペコードに加算される 0 から 7 までのレジスタコード。 結果として 1 バイトのオペコードとなる。 |
reg(/0 - /7指定の場合)
- regは、/0 - /7を指定された場合はそれをそのまま使う
もちろんこれは10進数表記なので、2進数に直すと以下のようになる。ModR/Mバイトのregフィールドはこれで埋まるわけだ。
/0 - /7 | 2進数表記 |
---|---|
/0 | 000 |
/1 | 001 |
/2 | 010 |
/3 | 011 |
/4 | 100 |
/5 | 101 |
/6 | 110 |
/7 | 111 |
reg(/0 - /7指定の場合)の実例
- 0x80 /7 ib をアセンブル
; 0x80 /7 ib CMP r/m8, imm8 ; 例 CMP CL,18 ; オペコードは0x80で確定 ; --------------------- ; ModR/Mの値は ; [mod] 11 ; [reg] 111 ; [r/m] 001 ; => "11111001" ; => 0xf9 ; --------------------- ; 18は16進数で0x12 ; --------------------- ; よって、以下がアセンブルされると CMP CL,18 ; 以下のバイナリが出力される 0x80, 0xf9, 0x12
reg('''/r'''指定の場合)
- regは、レジスタコードを指定する
つまり、mod2bitに続いて、regとr/mが3bitずつ続くことになる
reg(/r指定の場合)の実例
- '''0x69 /r iw''' をアセンブル
; 0x69 /r iw IMUL r32, imm32 ; 例 IMUL ECX,4608 ; オペコードは0x69で確定 ; --------------------- ; ModR/Mの値は ; [mod] 11 ; [reg] 001 ; [r/m] 001 ; => "11001001" ; => 0xc9 ; --------------------- ; 4608は16進数で0x1200 ; リトルエンディアンのため、 0x00, 0x12と並ぶ ; --------------------- ; よって、以下がアセンブルされると IMUL ECX,4608 ; 以下のバイナリが出力される 0x69, 0xc9, 0x00, 0x12
/r指定の場合のレジスタの細かい指定
さて、実はここまでregとr/mのどちらがどちらのレジスタを指定しているのか気になった人がいるかもしれない。その指摘はめっちゃ正しい。
ここのサイトに答えが書いてある。
The d bit in the opcode determines which operand is the source, and which is the destination:
d=0: MOD R/M <- REG, REG is the source
d=1: REG <- MOD R/M, REG is the destination
"d"bitというのは、1byte(8bit)のデータを先頭から数えて4番目のbitである。*1
つまり、"d"bitが0か1かによってmodとr/mの3bitをそれぞれ入れ替えなければいけない。
C++の疑似コード、std::bitsetを使うとやりやすい
uint8_t op = 0x8e; std::bitset<8> bsl(op); // オペコード if (bsl[3]) { // d=0 or 1 // d=1: REG <- MOD R/M, REG is the destination } else { // d=0: MOD R/M <- REG, REG is the source }
はじめて読む486、ModRMとかに関してはほとんど役に立たず…
- 作者: 蒲地輝尚
- 出版社/メーカー: アスキー
- 発売日: 1994/09
- メディア: 単行本
- 購入: 20人 クリック: 165回
- この商品を含むブログ (84件) を見る
*1:わかるか…!こんな細かい仕様…!
Let's Encryptを手動更新
だいたいここの指示にしたがえばよし
こんなエラーが出た。
Cleaning up challenges Attempting to renew cert from /etc/letsencrypt/renewal/freestylewiki.xyz.conf produced an unexpected error: At least one of the required ports is already taken.. Skipping.
httpdを一回停止させればOK
# systemctl stop httpd
成功時のログ
* Pythonのスクリプトがいろいろやってる(秘密鍵更新+CSR作成+証明書作成(中間証明書も))
[root@freestylewiki letsencrypt]# ./certbot-auto renew --force-renew Saving debug log to /var/log/letsencrypt/letsencrypt.log ------------------------------------------------------------------------------- Processing /etc/letsencrypt/renewal/freestylewiki.xyz.conf ------------------------------------------------------------------------------- Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org Renewing an existing certificate Performing the following challenges: tls-sni-01 challenge for freestylewiki.xyz Waiting for verification... Cleaning up challenges Generating key (2048 bits): /etc/letsencrypt/keys/0001_key-certbot.pem Creating CSR: /etc/letsencrypt/csr/0001_csr-certbot.pem ------------------------------------------------------------------------------- new certificate deployed without reload, fullchain is /etc/letsencrypt/live/freestylewiki.xyz/fullchain.pem ------------------------------------------------------------------------------- Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/freestylewiki.xyz/fullchain.pem (success)
Heroku + Plack + plenvを試す
ある目的のためにPlackをHerokuに上げたいと思っていた。で、試したので手順を書いておく。
plack-testing
今回試したリポジトリ
github.com
手順
初期設定
plenv
Rubyで言うところのrbenv、結構古いPerlじゃないと依存関係がぶっ壊れる
$ git clone git://github.com/tokuhirom/plenv.git ~/.plenv $ git clone git://github.com/tokuhirom/Perl-Build.git ~/.plenv/plugins/perl-build/ $ echo 'export PATH="$HOME/.plenv/bin:$PATH"' >> ~/.bash_profile $ echo 'eval "$(plenv init -)"' >> ~/.bash_profile $ exec $SHELL -l $ plenv install 5.16.3
cpanm
- cpan minusという意味らしい、cpan plusというcpanの拡張版の機能軽量化版だと思われる
- Rubyで言うところのGemfileである
- cpanfileに依存関係を記述する、そんでcpanmを実行
$ mkdir bin $ cd bin $ curl -LOk http://xrl.us/cpanm $ chmod +x cpanm
インストールとアプリケーションサーバの起動
$ bin/cpanm -L . --installdeps . $ ./start.sh
Heroku / Heroku buildpack: Perl
- ここ必見、HerokuにPerlのアプリケーションを上げる時、これが使える
- heroku createがHeroku上にアプリを登録する
- git push heroku masterは今のコードをHerokuにデプロイする、まあなんてクリアなコードでデプロイ出来るんでしょう
$ heroku create --buildpack http://github.com/pnu/heroku-buildpack-perl.git $ git push heroku master Counting objects: 22, done. Delta compression using up to 4 threads. Compressing objects: 100% (20/20), done. Writing objects: 100% (22/22), 3.04 KiB | 0 bytes/s, done. Total 22 (delta 7), reused 0 (delta 0) remote: Compressing source files... done. remote: Building source: remote: remote: -----> Perl/PSGI app detected remote: -----> Vendoring https://heroku-buildpack-perl.s3.amazonaws.com/cedar-14/perl-5.16.3.tgz remote: -----> Vendoring https://heroku-buildpack-perl.s3.amazonaws.com/cedar-14/perl-5.16.3-extras.tgz remote: -----> Current perl version is 5.16.3 remote: -----> Random RELEASE_UUID=794f391bff3b74b4946ff4ecebd3aad70b87ea46915f22c782a1b6762b0d08ee remote: -----> Bootstrapping cpanm and local::lib remote: Successfully installed App-cpanminus-1.7042 (upgraded from 1.7014) remote: Successfully installed local-lib-2.000019 (upgraded from 2.000014) remote: 2 distributions installed remote: -----> Installing dependencies (cpanm) remote: Successfully installed JavaScript-Value-Escape-0.07 remote: Successfully installed Plack-Middleware-ConsoleLogger-0.05 remote: Successfully installed CGI-4.33 (upgraded from 3.59) remote: Successfully installed CGI-Emulate-PSGI-0.22 remote: Successfully installed CGI-Compile-0.21 remote: Successfully installed Plack-Middleware-Auth-Digest-0.05 remote: Successfully installed Plack-Middleware-Deflater-0.12 remote: Successfully installed AnyEvent-HTTP-2.23 remote: Successfully installed Plack-App-Proxy-0.29 remote: Successfully installed CGI-PSGI-0.15 remote: Successfully installed asa-1.03 remote: Successfully installed IO-Handle-Util-0.01 remote: Successfully installed Any-Moose-0.26 remote: Successfully installed FCGI-Client-0.08 remote: Successfully installed Text-MicroTemplate-0.24 remote: Successfully installed Plack-Middleware-Debug-0.16 remote: Successfully installed Test-HexString-0.03 remote: Successfully installed Net-FastCGI-0.14 remote: Successfully installed Canary-Stability-2012 remote: Successfully installed Coro-6.511 remote: Successfully installed Net-Server-Coro-1.3 remote: Successfully installed Corona-0.1004 remote: Successfully installed Plack-Middleware-Header-0.04 remote: Successfully installed PSGI-1.102 remote: Successfully installed Server-Starter-0.32 remote: Successfully installed IO-Socket-IP-0.38 remote: Successfully installed Test-TCP-2.17 (upgraded from 2.06) remote: Successfully installed Class-Accessor-Lite-0.08 (省略) remote: Successfully installed Proc-Wait3-0.05 remote: Successfully installed IPC-Signal-1.00 remote: Successfully installed Signal-Mask-0.008 remote: Successfully installed Parallel-Prefork-0.18 remote: Successfully installed Starlet-0.30 remote: Successfully installed Cookie-Baker-0.07 remote: Successfully installed Plack-Middleware-Session-0.30 remote: Successfully installed Task-Plack-0.28 remote: 36 distributions installed remote: -----> Installing Starman remote: Successfully installed Starman-0.4014 (upgraded from 0.4010) remote: 1 distribution installed remote: -----> Caching local to /app/tmp/cache/perl/cedar-14/ remote: -----> Discovering process types remote: Procfile declares types -> (none) remote: Default types for buildpack -> web remote: remote: -----> Compressing... remote: Done: 31M remote: -----> Launching... remote: Released v4 remote: https://thawing-savannah-27493.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy.... done. To https://git.heroku.com/thawing-savannah-27493.git