Pointers x86程序集,将数据从阵列移动到寄存器

Pointers x86程序集,将数据从阵列移动到寄存器,pointers,assembly,x86,Pointers,Assembly,X86,我一遍又一遍地看这本书,不明白为什么这会给我“不正确的操作数类型”。它应该有用 这是Visual Studio中的内联程序集 function(unsigned int* a){ unsigned int num; _asm { mov eax, a //This stores address (start of the array) in eax mov num, dword ptr [eax*4] //This is the line I am having issues with.

我一遍又一遍地看这本书,不明白为什么这会给我“不正确的操作数类型”。它应该有用

这是Visual Studio中的内联程序集

function(unsigned int* a){
unsigned int num;

_asm {

mov eax, a //This stores address (start of the array) in eax
mov num, dword ptr [eax*4] //This is the line I am having issues with.
最后一行,我试图存储数组中的4字节值。但是我得到了错误C2415:操作数类型不正确


我做错了什么?如何将数组中的4字节值复制到32位寄存器中?

在Visual C++的内联汇编中,所有变量都作为内存操作数1访问;换句话说,无论您在哪里编写
num
,都可以认为编译器将取代
dword ptr[ebp-something]

现在,这意味着在最后一个
mov
中,您实际上是在尝试执行x86上未提供的内存
mov
。请改用临时寄存器:

mov eax, dword ptr [a]     ; load value of 'a' (which is an address) in eax
mov eax, dword ptr [eax]   ; dereference address, and load contents in eax
mov dword ptr [num], eax   ; store value in 'num'
请注意,我删除了*4,因为将指针乘以4是没有意义的-也许您打算使用
a
作为基数加上一些其他索引



1其他编译器,如gcc,提供了更精细地控制内联汇编和编译器生成代码之间交互的方法,这提供了极大的灵活性和能力,但有一个相当陡峭的学习曲线,需要非常小心才能使一切正常

在Visual C++的内联汇编中,所有变量都作为内存操作数1访问;换句话说,无论您在哪里编写
num
,都可以认为编译器将取代
dword ptr[ebp-something]

现在,这意味着在最后一个
mov
中,您实际上是在尝试执行x86上未提供的内存
mov
。请改用临时寄存器:

mov eax, dword ptr [a]     ; load value of 'a' (which is an address) in eax
mov eax, dword ptr [eax]   ; dereference address, and load contents in eax
mov dword ptr [num], eax   ; store value in 'num'
请注意,我删除了*4,因为将指针乘以4是没有意义的-也许您打算使用
a
作为基数加上一些其他索引




1其他编译器,如gcc,提供了更精细地控制内联汇编和编译器生成代码之间交互的方法,这提供了极大的灵活性和能力,但有一个相当陡峭的学习曲线,需要非常小心才能使一切正常

*4应该是刻度。我用得不对吗?这里是我的意思-它应该指定要复制的字节数在英特尔表示法中,要复制的字节数隐含在源值中-
dword ptr
指定您的源是存储在给定位置的dword(=4字节)。在给定数组开始和元素索引的情况下,当您想要访问数组的某个特定元素时,可以使用索引和比例-如果您有一个dword数组,该数组从存储在ebx中的地址开始,您可以通过
mov目标、dword ptr[ebx+eax*4]
访问eax th元素。MASM解释
mov reg、[mem]
mov reg,mem
相同。括号对于变量和其他内存操作数是隐式的。我相信这就是你在第一句话中想说的。如果你想在像NASM这样的汇编程序中获得正常的
mov-reg,mem
行为,你可以使用
mov-reg,OFFSET-mem
@CodyGray:不幸的是,我对MASM语法一点也不精通,我的大部分汇编知识来自反汇编/逆向工程和一些小规模的NASM操作;无论如何,更正是好的,这正是我的意思;没有换行。这不是“提问”框。如果你有新问题,@duxa.The*4应该是刻度。我用得不对吗?这里是我的意思-它应该指定要复制的字节数在英特尔表示法中,要复制的字节数隐含在源值中-
dword ptr
指定您的源是存储在给定位置的dword(=4字节)。在给定数组开始和元素索引的情况下,当您想要访问数组的某个特定元素时,可以使用索引和比例-如果您有一个dword数组,该数组从存储在ebx中的地址开始,您可以通过
mov目标、dword ptr[ebx+eax*4]
访问eax th元素。MASM解释
mov reg、[mem]
mov reg,mem
相同。括号对于变量和其他内存操作数是隐式的。我相信这就是你在第一句话中想说的。如果你想在像NASM这样的汇编程序中获得正常的
mov-reg,mem
行为,你可以使用
mov-reg,OFFSET-mem
@CodyGray:不幸的是,我对MASM语法一点也不精通,我的大部分汇编知识来自反汇编/逆向工程和一些小规模的NASM操作;无论如何,更正是好的,这正是我的意思;没有换行。这不是“提问”框。如果你有一个新问题,@duxa,请注意这个问题。在单个MOV操作中,不存在将内存操作数移动到另一个内存操作数的情况。你必须使用一个临时寄存器。但我正在从一个内存移到另一个内存,然后从一个寄存器移到另一个内存,两个独立的操作,没有将内存复制到内存?
num
不是寄存器。
mov num,dword ptr[eax*4]
的两个操作数当然都是内存,
eax*4
没有意义。为什么要将指针缩放4?您可能需要
eax+4
。不过,老实说,使用内联汇编来实现这一点没有什么意义。只需让编译器生成代码。它将比在内联汇编中编写的任何操作都更有效。可能的重复操作在单个MOV操作中不会将内存操作数移动到另一个内存操作数。你必须使用一个临时寄存器。但我正在从一个内存移到另一个内存,然后从一个寄存器移到另一个内存,两个独立的操作,没有将内存复制到内存?
num
不是寄存器。
mov num,dword ptr[e]的两个操作数