无法写入 x64 程序集中使用 malloc/calloc 请求的内存

Can't write to memory requested with malloc/calloc in x64 Assembly

这是我在这个平台上的第一个问题。我正在尝试修改图像文件的像素并将它们复制到 calloc 请求的内存中。当代码尝试取消引用指向用 calloc 在偏移量 16360 处请求写入的内存的指针时,将抛出“访问冲突写入位置”异常。有时偏移量会略高或略低。请求的内存量是正确的。当我使用 calloc 在 C++ 中编写等效代码时,它可以工作,但不能在汇编中使用。我还尝试在程序集中请求更多内存,并在 visual studio 设置中增加堆和堆栈大小,但对程序集代码没有任何作用。在构建和 运行 程序之前,我还必须设置选项 /LARGEADDRESSAWARE:NO。

我知道 AVX 指令集更适合这个,但是代码会包含更多的行,所以我把这个问题做得更简单,我也不是专业人士,我这样做是为了练习AVX指令集。

非常感谢:)

    const uint8_t* getImagePtr(sf::Image** image, const char* imageFilename, uint64_t* imgSize) {
        sf::Image* img = new sf::Image;
        img->loadFromFile(imageFilename);
        sf::Vector2u sz = img->getSize();
        *imgSize = uint64_t((sz.x * sz.y) * 4u);
        *image = img;
        return img->getPixelsPtr();
    }
EXTRN getImagePtr:PROC
EXTRN calloc:PROC

.data
imagePixelPtr QWORD 0 ; contains address to source array of 8 bit pixels
imageSize QWORD 0 ; contains size in bytes of the image file
image QWORD 0 ; contains pointer to image object
newImageMemory QWORD 0 ; contains address to destination array
imageFilename BYTE "IMAGE.png", 0 ; name of the file

.code
mainasm PROC

sub rsp, 40
mov rcx, OFFSET image
mov rdx, OFFSET imageFilename
mov r8, OFFSET imageSize
call getImagePtr

mov imagePixelPtr, rax

mov rcx, 1
mov rdx, imageSize
call calloc
add rsp, 40

cmp rax, 0
je done

mov newImageMemory, rax

mov rcx, imageSize
xor eax, eax
mov bl, 20

SomeLoop:

mov dl, BYTE PTR [imagePixelPtr + rax]
add dl, bl
mov BYTE PTR [newImageMemory + rax], dl ; exception when dereferencing and writing to offset 16360

inc rax
loop SomeLoop

done:
ret
mainasm ENDP
END

让我们把这行翻译回 C:

mov BYTE PTR [newImageMemory + rax], dl ;

在 C 中,这或多或少等同于:

*((unsigned char *)&newImageMemory + rax) = dl;

这显然不是你想要的。它正在写入 newImageMemory 位置的偏移量,而不是 newImageMemory 指向的偏移量。

如果要将 newImageMemory 用作偏移量的基地址,则需要将其保存在寄存器中。

当我们这样做时,这一行也是错误的,原因相同:

mov dl, BYTE PTR [imagePixelPtr + rax]

刚好没崩溃