1

「記憶場所」の定義に困っています。「Intel 64 and IA-32 Software Developer's Manual」によると、多くの命令でメモリ位置をオペランドとして使用できます。たとえば、MOVBE (バイトをスワップした後にデータを移動):
命令: MOVBE m32 , r32

問題は、メモリの場所をどのように定義するかです。.bss セクションで定義された変数を使用しようとしました:

section .bss
    memory: resb 4          ;reserve 4 byte
    memorylen: equ $-memory

section .text
global _start

_start:
    MOV R9D, 0x6162630A
    MOV [memory], R9D
    SHR [memory], 1
    MOVBE [memory], R9D

編集:->

    MOV EAX, 0x01
    MOV EBX, 0x00
    int 0x80

<-EDIT
SHR がコメント アウトされている場合、yasm (yasm -f elf64 .asm) は問題なくコンパイルされますが、stdio を実行すると、次のように表示されます: Illegal Instruction
また、MOVBE がコメント アウトされている場合、コンパイル時に次のエラーが発生します:エラー: オペランド 1 のサイズが無効です

命令セットのリファレンスで示されている「m」オプションを使用するためにメモリを割り当てるにはどうすればよいですか?
[CPU=x64、コンパイラ=yasm]

4

1 に答える 1

2

それがすべてのコードである場合、最後に初期化されていない領域に落ちているため、エラーが発生します。これは、正しく行ったメモリの割り当てとは関係ありません。exit システム コールを使用してプログラムを終了するコードを追加するか、少なくともエンドレス ループを配置して障害を回避する必要があります (ctrl+cまたは同等の方法を使用してプログラムを強制終了します)。

更新: 上記は当てはまりますが、すべてがサポートしているわけではないため、CPU が命令をillegal instructionサポートしていないことが原因である可能性が高くなります。MOVBEリファレンスを見ると、命令のリーフによって返されたレジスタ内の特定のフラグ ビットがこの命令のサポートを示して#UD If CPUID.01H:ECX.MOVBE[bit 22] = 0.いることを伝えようとしていることがわかります。Linux を使用している場合は、フラグがあるかどうかを簡単に確認できます。ECX01CPUID/proc/cpuinfomovbe

無効なオペランド サイズについては、通常、命令から推定できない場合にオペランド サイズを指定する必要があります。つまり、SHRすべてのサイズ (byte、word、dword、qword) を受け入れるため、実際にはそのエラーはまったく発生しないはずですが、予期しないデフォルト サイズの操作が発生する可能性があります。この場合に使用する必要がSHR dword [memory], 1あり、それもまたyasm嬉しいことです。

ああ、インテルのマニュアルを読むための +1 ;)

于 2014-11-16T02:23:48.593 に答える