asm usage of memory location operands

2019-08-14 17:32发布

问题:

I am in trouble with the definition 'memory location'. According to the 'Intel 64 and IA-32 Software Developer's Manual' many instruction can use a memory location as operand. For example MOVBE (move data after swapping bytes):
Instruction: MOVBE m32, r32

The question is now how a memory location is defined; I tried to use variables defined in the .bss section:

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

EDIT:->

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

<-EDIT
If SHR is commented out yasm (yasm -f elf64 .asm) compiles without problems but when executing stdio shows: Illegal Instruction
And if MOVBE is commented out the following error occurs when compiling: error: invalid size for operand 1

How do I have to allocate memory for using the 'm' option shown by the instruction set reference?
[CPU=x64, Compiler=yasm]

回答1:

If that is all your code, you are falling off at the end into uninitialized region, so you will get a fault. That has nothing to do with allocating memory, which you did right. You need to add code to terminate your program using an exit system call, or at least put an endless loop so you avoid the fault (kill your program using ctrl+c or equivalent).

Update: While the above is true, the illegal instruction here is more likely caused by the fact that your cpu simply does not support the MOVBE instruction, because not all do. If you look in the reference, you can see it says #UD If CPUID.01H:ECX.MOVBE[bit 22] = 0. That is trying to tell you that a particular flag bit in the ECX register returned by the 01 leaf of the CPUID instruction shows support of this instruction. If you are on linux, you can conveniently check in /proc/cpuinfo whether you have the movbe flag or not.

As for the invalid operand size: you should generally specify the operand size when it can not be deduced from the instruction. That said, SHR accepts all sizes (byte, word, dword, qword) so you should really not get that error at all, but you might get an operation of unexpected default size. You should use SHR dword [memory], 1 in this case, and that also makes yasm happy.

Oh, and +1 for reading the intel manual ;)