我在定义'内存位置'时遇到了麻烦。根据“Intel 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
< - 编辑
如果SHR被注释掉yasm(yasm -f elf64 .asm)编译没有问题但是在执行stdio时显示:非法指令
如果MOVBE被注释掉,编译时会出现以下错误:错误:操作数1的大小无效
如何使用指令集参考所示的'm'选项分配内存?
[CPU = x64,Compiler = yasm]
答案 0 :(得分:2)
如果那是您的全部代码,那么您最终会进入未初始化区域,因此您将遇到错误。这与分配内存无关,你做得对。您需要使用退出系统调用添加代码来终止程序,或者至少进行无限循环以避免错误(使用ctrl+c
或同等程序终止程序)。
更新:虽然上述情况属实,但illegal instruction
更可能是因为你的cpu根本不支持MOVBE
指令,因为并非所有指令都支持#UD If CPUID.01H:ECX.MOVBE[bit 22] = 0.
。如果您查看引用,您可以看到ECX
它试图告诉您01
寄存器中CPUID
寄存器返回的特定标志位/proc/cpuinfo
指令显示对该指令的支持。如果您使用的是Linux,则可以方便地检查movbe
是否有SHR
标记。
对于无效的操作数大小:通常应指定无法从指令推导出的操作数大小。也就是说,SHR dword [memory], 1
接受所有大小(字节,单词,双字,双字),因此您根本不应该得到该错误,但是您可能会获得意外默认大小的操作。在这种情况下,您应该使用yasm
,这也使{{1}}感到满意。
哦,还有+1阅读英特尔手册;)