1

我在定义“内存位置”时遇到了麻烦。根据“英特尔 64 和 IA-32 软件开发人员手册”,许多指令可以使用内存位置作为操作数。例如 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 时显示:非法指令
如果 MOVBE 被注释掉,编译时会出现以下错误:错误:操作数 1 的大小无效

如何为使用指令集参考中显示的“m”选项分配内存?
[CPU=x64,编译器=yasm]

4

1 回答 1

2

如果这就是您的全部代码,那么您最终会掉入未初始化的区域,因此您会遇到错误。这与分配内存无关,你做得对。您需要添加代码以使用退出系统调用终止您的程序,或者至少放置一个无限循环以避免错误(使用ctrl+c或等效终止您的程序)。

更新:虽然上述情况属实,但illegal instruction这里更可能是由于您的 cpu 根本不支持该MOVBE指令,因为并非所有人都支持。如果您查看参考资料,您会看到它说#UD If CPUID.01H:ECX.MOVBE[bit 22] = 0.这是试图告诉您指令叶ECX返回的寄存器中的特定标志位显示支持该指令。如果你在linux上,你可以方便地检查你是否有flag。01CPUID/proc/cpuinfomovbe

至于无效的操作数大小:当不能从指令中推导出来时,一般应指定操作数大小。也就是说,SHR接受所有大小(字节、字、dword、qword),所以你根本不应该得到那个错误,但你可能会得到一个意外的默认大小的操作。你应该SHR dword [memory], 1在这种情况下使用,这也让人yasm高兴。

哦,阅读英特尔手册 +1 ;)

于 2014-11-16T02:23:48.593 回答