Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 在32位和64位汇编语言中使用malloc()分配内存_Windows_Assembly_X86_Malloc_X86 64 - Fatal编程技术网

Windows 在32位和64位汇编语言中使用malloc()分配内存

Windows 在32位和64位汇编语言中使用malloc()分配内存,windows,assembly,x86,malloc,x86-64,Windows,Assembly,X86,Malloc,X86 64,我必须做一个64位堆栈。为了让自己适应malloc,我设法将两个整数(32位)写入内存并从中读取: 但是,当我尝试使用64位执行此操作时: 第一段代码运行良好。正如Jester所建议的,您将64位值分为两部分(32位)。这是在32位体系结构上执行此操作的方式。您没有可用的64位寄存器,并且无法一次写入64位内存块。但你似乎已经知道了,所以我不会再重复了 在第二段代码中,您尝试以64位体系结构(x86-64)为目标。现在,您不再需要在两个32位的一半中写入64位值,因为64位体系结构本机支持64

我必须做一个64位堆栈。为了让自己适应malloc,我设法将两个整数(32位)写入内存并从中读取:

但是,当我尝试使用64位执行此操作时:


第一段代码运行良好。正如Jester所建议的,您将64位值分为两部分(32位)。这是在32位体系结构上执行此操作的方式。您没有可用的64位寄存器,并且无法一次写入64位内存块。但你似乎已经知道了,所以我不会再重复了

在第二段代码中,您尝试以64位体系结构(x86-64)为目标。现在,您不再需要在两个32位的一半中写入64位值,因为64位体系结构本机支持64位整数。您有64位宽的寄存器可用,并且可以直接将64位块写入内存。利用这一点简化(并加速)代码

64位寄存器是
Rxx
而不是
Exx
。当您使用
QWORD PTR
时,您将希望使用
Rxx
;使用
DWORD PTR
时,需要使用
Exx
。两者在64位代码中都是合法的,但在32位代码中只有32位DWORD是合法的

还有几件事需要注意:

  • 虽然使用
    MOV xxx,0
    清除寄存器是完全有效的,但这通常是您应该编写的。这是一个非常古老的技巧,任何汇编语言程序员都应该知道这一点,如果你试图阅读别人的汇编程序,你就需要熟悉这个习惯用法。(但实际上,在您编写的代码中,根本不需要这样做。有关原因,请参见第2点。)

  • 在64位模式下,您可以简单地编写
    XOR-eax,eax
    ,而不是
    XOR-rax,rax
    。这是,再次,更小和更快

  • 64位程序的调用约定与32位程序中使用的调用约定不同。根据您使用的操作系统的不同,调用约定的具体规格也会有所不同。正如Peter Cordes所评论的,在。Windows和Linux x64调用约定都至少在寄存器中传递前4个整数参数(而不是像x86-32调用约定那样在堆栈上),但实际使用的寄存器不同。此外,对于调用函数之前必须如何设置堆栈,64位调用约定与32位调用约定有不同的要求

  • (因为您的屏幕截图显示了一些关于“MASM”的信息,所以我假设您在下面的示例代码中使用的是Windows。)

    如果您想在32位的一半中完成这项工作,即使是在64位体系结构上,您当然可以。这将如下所示:

    sub  rsp, 40                   ; set up stack
    
    mov  ecx, 8                    ; request 8 bytes
    call malloc                    ; allocate memory
    
    mov  dword ptr [eax],   1      ; write "1" into low 32 bits
    mov  dword ptr [eax+4], 2      ; write "2" into high 32 bits
    
    ; ... do whatever
    
    add  rsp, 40                   ; clean up stack
    
    请注意,最后两条
    MOV
    指令与您在32位版本的代码中编写的指令相同。这是有道理的,因为你正在做完全相同的事情

    您最初编写的代码不起作用的原因是
    EAX
    不包含
    QWORD PTR
    ,它包含
    DWORD PTR
    。因此,汇编程序生成了“无效指令操作数”错误,因为存在不匹配。这与不偏移8的原因相同,因为DWORD PTR只有4个字节。一个
    qwordptr
    实际上是8个字节,但是在
    EAX
    中没有一个字节

    或者,如果要写入16个字节:

    sub  rsp, 40                   ; set up stack
    
    mov  ecx, 16                   ; request 16 bytes
    call malloc                    ; allocate memory
    
    mov  qword ptr [rax],   1      ; write "1" into low 64 bits
    mov  qword ptr [rax+8], 2      ; write "2" into high 64 bits
    
    ; ... do whatever
    
    add  rsp, 40                   ; clean up stack
    

    比较这三段代码,确保您理解它们的区别以及为什么需要按原样编写它们

    不能直接将64位整数写入内存。您必须分两半完成,例如,
    mov dword ptr[eax],1;mov dword ptr[eax+4],0
    。粘贴代码而不是此屏幕截图。您的64位版本是否应该是x86-64,因为您使用的是
    qword ptr
    ?如果是这样,64位调用约定就不同了。。。请参阅第二段代码,您试图以64位体系结构为目标。。。或者他只是想在32位模式下存储一个64位整数。还请注意,
    mov qword ptr[rax],1
    仅适用于32位符号扩展立即数。
    sub  rsp, 40                   ; set up stack
    
    mov  ecx, 16                   ; request 16 bytes
    call malloc                    ; allocate memory
    
    mov  qword ptr [rax],   1      ; write "1" into low 64 bits
    mov  qword ptr [rax+8], 2      ; write "2" into high 64 bits
    
    ; ... do whatever
    
    add  rsp, 40                   ; clean up stack