ページへ戻る
印刷
GUIGUI01/memo30
をテンプレートにして作成 ::
OSASK計画
osaskwiki
:GUIGUI01/memo30 をテンプレートにして作成
開始行:
TITLE:x
* ぐいぐい01に関するメモ-30
-(by [[K]], 2009.08.03)
-メモのうち重要な部分をそのうちまとめてまともなページを作る
*** (42) naskで.g01アプリを作るには?(1)
-[[impressions]]の2009-07-26ごろのfshinoさんのリクエスト...
-文脈的には[[GUIGUI01/memo27]]の続きだけど、あっちはC言語...
----
-何はともあれ、まずは文字列表示を使って"hello, world\n"を...
; ex0025.nas
[FORMAT "WCOFF"]
[FILE "ex0025.nas"]
[INSTRSET "i486p"]
[BITS 32]
GLOBAL _G01Main
EXTERN _g01_execcmd0
[SECTION .text]
_G01Main:
MOV EAX,msg
CALL _g01_execcmd0
DB 0x53, 0x00 ; g01_putstr0((char *) EA...
RET
[SECTION .data]
msg DB "hello, world", 0x0a, 0
-これです。makeすると64バイトになるでしょう。Makefileは[[...
-要点は次の通りです。
--「CALL _g01_execcmd0 DB 0x53, 0x00」が、EAX番地からの文...
--(ポインタで指定する)文字列は.dataかもしくはスタック内...
--「CALL _g01_execcmd0」すると、ESIはある特別な値が代入さ...
---他のレジスタは原則として影響がない。
--CALLのあとにDBがあるのが気持ち悪いが、EDI=0でAPIを呼ん...
---というか、そのために_g01_execcmd0は内部でEDI=0にしてか...
--アプリの実行開始番地は_G01Mainに固定。
-EAX以外のレジスタを指定したい場合は次の通りです。
--「CALL _g01_execcmd0 DB 0x53, 0x10」が、ECX番地からの文...
--「CALL _g01_execcmd0 DB 0x53, 0x20」が、EDX番地からの文...
--「CALL _g01_execcmd0 DB 0x53, 0x30」が、EBX番地からの文...
----
-次は1文字表示APIです。
; ex0026.nas
[FORMAT "WCOFF"]
[FILE "ex0026.nas"]
[INSTRSET "i486p"]
[BITS 32]
GLOBAL _G01Main
EXTERN _g01_execcmd0
[SECTION .text]
_G01Main:
MOV AL,0x20
.putc_loop
CALL _g01_execcmd0
DB 0x55, 0x16, 0x00 ; g01_putc(EAX);
INC EAX
CMP AL,0x7e
JBE .putc_loop
MOV AL,0x0a
CALL _g01_execcmd0
DB 0x55, 0x16, 0x00 ; g01_putc(EAX);
RET
-これです。makeすると57バイトになるでしょう。
-要点は次の通りです。
--「CALL _g01_execcmd0 DB 0x55, 0x16, 0x00」が、putc(EAX)...
-ちなみにこれもレジスタを選べます。
--「CALL _g01_execcmd0 DB 0x55, 0x16, 0x10」が、putc(ECX)...
--「CALL _g01_execcmd0 DB 0x55, 0x16, 0x20」が、putc(EDX)...
--「CALL _g01_execcmd0 DB 0x55, 0x16, 0x30」が、putc(EBX)...
-こんな感じで分かるでしょうか?
----
-ここで、「CALL _g01_execcmd0」の正体を明かしたいと思いま...
EXTERN _g01_esi0
_g01_execcmd0:
XOR EDI,EDI
MOV ESI,[_g01_esi0]
JMP [ESI] ; これがAPI呼び出し。RET...
-だからEDIが0になるとか、ESIの値が上書きされるなんてこと...
-これを利用すると、ex0026.nasは次のように書き換えられます。
; ex0026.nas
[FORMAT "WCOFF"]
[FILE "ex0026.nas"]
[INSTRSET "i486p"]
[BITS 32]
GLOBAL _G01Main
EXTERN _g01_esi0
[SECTION .text]
_G01Main:
MOV AL,0x20
XOR EDI,EDI
MOV ESI,[_g01_esi0]
.putc_loop
CALL [ESI]
DB 0x55, 0x16, 0x00 ; g01_putc(EAX);
INC EAX
CMP AL,0x7e
JBE .putc_loop
MOV AL,0x0a
CALL [ESI]
DB 0x55, 0x16, 0x00 ; g01_putc(EAX);
RET
-これです。makeすると56バイトになるでしょう。ちょっとだけ...
-さらに小さくすることもできます。実は.g01アプリが実行され...
; ex0026.nas
[FORMAT "WCOFF"]
[FILE "ex0026.nas"]
[INSTRSET "i486p"]
[BITS 32]
GLOBAL _G01Main
[SECTION .text]
_G01Main:
MOV AL,0x20
.putc_loop
CALL [ESI]
DB 0x55, 0x16, 0x00 ; g01_putc(EAX);
INC EAX
CMP AL,0x7e
JBE .putc_loop
MOV AL,0x0a
CALL [ESI]
DB 0x55, 0x16, 0x00 ; g01_putc(EAX);
RET
-短くなりました。
-このテクニックは、もちろんex0025.nasにも有効です。今後は...
----
-次は文字列定数の表示です。
-ex0025では、文字列のアドレスをレジスタを使って渡したわけ...
; ex0027.nas
[FORMAT "WCOFF"]
[FILE "ex0027.nas"]
[INSTRSET "i486p"]
[BITS 32]
GLOBAL _G01Main
EXTERN _g01_execcmd0
[SECTION .text]
_G01Main:
CALL _g01_execcmd0
DB 0x51, "hello, world", 0x0a, 0x00 ; g...
RET
-これはmakeすると57バイトになるでしょう。ex0025と比べて7...
-要点は次の通りです。
--「CALL _g01_execcmd0 DB 0x51, ...」が、g01_putstr0(...)...
--文字列なので終端の0x00を忘れずに。
-ちなみにここでは紹介していませんが、先の0x53でもこの0x51...
-この手法は、当然ex0026の末尾の改行コード出力にも使えます...
* こめんと欄
#comment
終了行:
TITLE:x
* ぐいぐい01に関するメモ-30
-(by [[K]], 2009.08.03)
-メモのうち重要な部分をそのうちまとめてまともなページを作る
*** (42) naskで.g01アプリを作るには?(1)
-[[impressions]]の2009-07-26ごろのfshinoさんのリクエスト...
-文脈的には[[GUIGUI01/memo27]]の続きだけど、あっちはC言語...
----
-何はともあれ、まずは文字列表示を使って"hello, world\n"を...
; ex0025.nas
[FORMAT "WCOFF"]
[FILE "ex0025.nas"]
[INSTRSET "i486p"]
[BITS 32]
GLOBAL _G01Main
EXTERN _g01_execcmd0
[SECTION .text]
_G01Main:
MOV EAX,msg
CALL _g01_execcmd0
DB 0x53, 0x00 ; g01_putstr0((char *) EA...
RET
[SECTION .data]
msg DB "hello, world", 0x0a, 0
-これです。makeすると64バイトになるでしょう。Makefileは[[...
-要点は次の通りです。
--「CALL _g01_execcmd0 DB 0x53, 0x00」が、EAX番地からの文...
--(ポインタで指定する)文字列は.dataかもしくはスタック内...
--「CALL _g01_execcmd0」すると、ESIはある特別な値が代入さ...
---他のレジスタは原則として影響がない。
--CALLのあとにDBがあるのが気持ち悪いが、EDI=0でAPIを呼ん...
---というか、そのために_g01_execcmd0は内部でEDI=0にしてか...
--アプリの実行開始番地は_G01Mainに固定。
-EAX以外のレジスタを指定したい場合は次の通りです。
--「CALL _g01_execcmd0 DB 0x53, 0x10」が、ECX番地からの文...
--「CALL _g01_execcmd0 DB 0x53, 0x20」が、EDX番地からの文...
--「CALL _g01_execcmd0 DB 0x53, 0x30」が、EBX番地からの文...
----
-次は1文字表示APIです。
; ex0026.nas
[FORMAT "WCOFF"]
[FILE "ex0026.nas"]
[INSTRSET "i486p"]
[BITS 32]
GLOBAL _G01Main
EXTERN _g01_execcmd0
[SECTION .text]
_G01Main:
MOV AL,0x20
.putc_loop
CALL _g01_execcmd0
DB 0x55, 0x16, 0x00 ; g01_putc(EAX);
INC EAX
CMP AL,0x7e
JBE .putc_loop
MOV AL,0x0a
CALL _g01_execcmd0
DB 0x55, 0x16, 0x00 ; g01_putc(EAX);
RET
-これです。makeすると57バイトになるでしょう。
-要点は次の通りです。
--「CALL _g01_execcmd0 DB 0x55, 0x16, 0x00」が、putc(EAX)...
-ちなみにこれもレジスタを選べます。
--「CALL _g01_execcmd0 DB 0x55, 0x16, 0x10」が、putc(ECX)...
--「CALL _g01_execcmd0 DB 0x55, 0x16, 0x20」が、putc(EDX)...
--「CALL _g01_execcmd0 DB 0x55, 0x16, 0x30」が、putc(EBX)...
-こんな感じで分かるでしょうか?
----
-ここで、「CALL _g01_execcmd0」の正体を明かしたいと思いま...
EXTERN _g01_esi0
_g01_execcmd0:
XOR EDI,EDI
MOV ESI,[_g01_esi0]
JMP [ESI] ; これがAPI呼び出し。RET...
-だからEDIが0になるとか、ESIの値が上書きされるなんてこと...
-これを利用すると、ex0026.nasは次のように書き換えられます。
; ex0026.nas
[FORMAT "WCOFF"]
[FILE "ex0026.nas"]
[INSTRSET "i486p"]
[BITS 32]
GLOBAL _G01Main
EXTERN _g01_esi0
[SECTION .text]
_G01Main:
MOV AL,0x20
XOR EDI,EDI
MOV ESI,[_g01_esi0]
.putc_loop
CALL [ESI]
DB 0x55, 0x16, 0x00 ; g01_putc(EAX);
INC EAX
CMP AL,0x7e
JBE .putc_loop
MOV AL,0x0a
CALL [ESI]
DB 0x55, 0x16, 0x00 ; g01_putc(EAX);
RET
-これです。makeすると56バイトになるでしょう。ちょっとだけ...
-さらに小さくすることもできます。実は.g01アプリが実行され...
; ex0026.nas
[FORMAT "WCOFF"]
[FILE "ex0026.nas"]
[INSTRSET "i486p"]
[BITS 32]
GLOBAL _G01Main
[SECTION .text]
_G01Main:
MOV AL,0x20
.putc_loop
CALL [ESI]
DB 0x55, 0x16, 0x00 ; g01_putc(EAX);
INC EAX
CMP AL,0x7e
JBE .putc_loop
MOV AL,0x0a
CALL [ESI]
DB 0x55, 0x16, 0x00 ; g01_putc(EAX);
RET
-短くなりました。
-このテクニックは、もちろんex0025.nasにも有効です。今後は...
----
-次は文字列定数の表示です。
-ex0025では、文字列のアドレスをレジスタを使って渡したわけ...
; ex0027.nas
[FORMAT "WCOFF"]
[FILE "ex0027.nas"]
[INSTRSET "i486p"]
[BITS 32]
GLOBAL _G01Main
EXTERN _g01_execcmd0
[SECTION .text]
_G01Main:
CALL _g01_execcmd0
DB 0x51, "hello, world", 0x0a, 0x00 ; g...
RET
-これはmakeすると57バイトになるでしょう。ex0025と比べて7...
-要点は次の通りです。
--「CALL _g01_execcmd0 DB 0x51, ...」が、g01_putstr0(...)...
--文字列なので終端の0x00を忘れずに。
-ちなみにここでは紹介していませんが、先の0x53でもこの0x51...
-この手法は、当然ex0026の末尾の改行コード出力にも使えます...
* こめんと欄
#comment
ページ名: