2016-07-11 11 views
1

私のコードがビルドされない問題がある16ビットNASMアセンブリで作業しています。私は、アセンブラは、変数が何であるかのサイズを知っていないため、この問題が発生したことを読んだエラー:操作サイズが指定されていません - NASm

section .bss 
    x_coord RESB 8 ; [x_coord] is the head, [x_coord+2] is the next cell, etc. 
    y_coord RESB 8 ; Same here 
    pixel_x RESB 2 ; Storage for calculations 
    pixel_y RESB 2 ; Storage for calculations 

    ... 


    MOV [pixel_x], [x_coord] 
    MOV [pixel_y], [y_coord] 
    CALL DrawPixel 

    MOV [pixel_x], [x_coord+2] 
    MOV [pixel_y], [y_coord+2] 
    CALL DrawPixel 

    MOV [pixel_x], [x_coord+4] 
    MOV [pixel_y], [y_coord+4] 
    CALL DrawPixel 

    MOV [pixel_x], [x_coord+6] 
    MOV [pixel_y], [y_coord+6] 
    CALL DrawPixel 

:エラーは、ここでは、すべてのMOVラインで発生します。私はMOV [pixel_x], byte [x_coord]いくつかのオンライン投稿によって提案したが、同じエラーが発生します。私はちょうどx_coordとy_coordの最初の2バイトをpixel_x/pixel_yにコピーし、次の2つをコピーしてから次の2つをコピーし、次の2つをコピーしたいだけです。どうすればこの作品を作れますか?

感謝:)

答えて

4

プロセッサは、一度で2バイトを移動する場合、使用することです、簡単なメモリ間移動命令、そうする権利ものを持っていません仲介者として登録します。

MOV ax, word [x_coord] 
MOV word [pixel_x], ax 
MOV ax, word [y_coord] 
MOV word [pixel_y], ax 
CALL DrawPixel 

あなたの変数がメモリに連続しているので、あなたもこれを行うことができるかもしれない:

MOV eax, dword [x_coord] ; move BOTH x_coord AND y_coord into the register 
MOV dword [pixel_x], eax ; populates BOTH pixel_x AND pixel_y 
CALL DrawPixel 

あなただけが通話を1つずつ行うことができ、4つのピクセルを描画している場合:あなたはより多くのピクセルを描画しない持っていた場合

MOV eax, dword [x_coord] 
MOV dword [pixel_x], eax 
CALL DrawPixel 
MOV eax, dword [x_coord+2] 
MOV dword [pixel_x], eax 
CALL DrawPixel 
MOV eax, dword [x_coord+4] 
MOV dword [pixel_x], eax 
CALL DrawPixel 
MOV eax, dword [x_coord+6] 
MOV dword [pixel_x], eax 
CALL DrawPixel 

、あなたはループを書いて考えるかもしれません。

(脇:。また、レジスタの値を使用するようにDrawPixelの実装を検討)

+0

これは完璧に見える、ありがとう!あなたの最後のコメントについては、このようなtemp値にどのようなレジスタを使用しても安全だと100%確信していないので、私はメモリを使用しました。これはどれがベストですか? – Nathan

+2

@Nathan:それは関数のABIに依存します。両方の関数を記述した場合は、独自の呼び出し規約を作成します。 [x86タグwiki](http://stackoverflow.com/tags/x86/info)の既存のABI /呼び出し規約を見てください。マイクロソフトの32ビット__vectorcallは、おそらく最初の2つの整数引数がレジスタに渡される16ビットコードの良い出発点です。 (edxおよびecx、IIRC)。 32bit SysV(Linux)はスタック上のargsを排他的に渡します。それはグローバルでargsを渡すよりも良い選択です。 ( 'push'はメモリオペランドで動作します)。 –

+0

@Nathan:そう、 'rdi'、' rsi'、 'rdx'、' rcx'、 'r8'、' r9':あなたは64ビットモードでNASMを使用している場合は、整数値のパラメータがこの順に渡されます2つの座標を 'rdi'の下位32ビット、つまり' edi 'にパックすることによって 'drawPixel'関数を記述することになります。関数内では、 'rbp'、' rbx'、 'r12'、' r13'、 'r14'、および' r15'を保持する必要があります。しかし、呼び出し規約(アライメント、浮動小数点レジスタ、戻り値など)を機能させるためには、これ以上のものがあります。http://www.nasm.us/doc/nasmdo11.htmlおよびhttp://x86-64.orgを参照してください。 /documentation/abi.pdf。 –

関連する問題