Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.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
Image processing x86:访问BMP图像的未对齐像素字节_Image Processing_Assembly_X86_Nasm - Fatal编程技术网

Image processing x86:访问BMP图像的未对齐像素字节

Image processing x86:访问BMP图像的未对齐像素字节,image-processing,assembly,x86,nasm,Image Processing,Assembly,X86,Nasm,我正在使用C+x86汇编(NASM)编写一个程序,该程序执行图像的旋转和缩放。为了做到这一点,它逐个遍历目标图像的像素,并计算源图像中相应的像素 汇编代码的该部分: ; buffer operations push ebx fistp dword loc ; store the number of src pixel mov dword ebx, loc ; move it to ebx imul ebx, 3 ; 3 bytes per pix

我正在使用C+x86汇编(NASM)编写一个程序,该程序执行图像的旋转和缩放。为了做到这一点,它逐个遍历目标图像的像素,并计算源图像中相应的像素

汇编代码的该部分:

; buffer operations
push ebx
fistp dword loc         ; store the number of src pixel
mov   dword ebx, loc    ; move it to ebx
imul ebx, 3             ; 3 bytes per pixel, so multiply pixel number by 3
mov dword eax, [ebx+esi]; store that pixel's color bytes ; ERROR, SEGSEV
mov dword [edi], eax    ; draw a pixel
pop ebx
特别是标有“ERROR,SEGSEV”的行会产生分段错误。 我想这是因为我试图访问未对齐的内存地址。 这就是说,bmp文件像素缓冲区的组织方式是,每个像素有一个接一个的B、G、R字节存储,因此每个像素有3个字节,每个像素的第一个字节在内存中的位置不能被4整除(例如:像素一:0.B、1.G、2.R;像素二:3.B、4.G、5.R-因此我必须访问地址3才能访问第二个像素)


问题是:如果不允许我访问未对齐的内存位置,那么我如何访问像素的数据?在处理bmp文件时通常是如何进行的?

OP假设x86体系结构无法访问未对齐的数据(地址上的数据不是所用寄存器大小的倍数),这是精简指令集计算(RISC)处理器中的一个常见问题。例如:

mov ebx, 0x12345677    ; Note the odd address
mov eax, [ebx]         ; Load a 32-bit register from an odd address
在RISC架构(如ARM或PowerPC)中,这确实会导致问题:总是(ARM)或如果不禁用(PowerPC)。在x86体系结构中,未对齐的访问始终是可能的(尽管有时会以速度为代价),而且直到486年以后,它才能够被检查;但这张支票几乎总是被拒之门外

事实证明,问题出在其他地方:

mov dword eax, [ebx+esi]; store that pixel's color bytes ; ERROR, SEGSEV
OP没有确认
esi
保持所需的值


不过,请注意,未与x86对齐的访问仍然会导致问题。所有段都定义为特定大小(即使该大小为4GiB)。接近该段顶部的访问可能会“溢出”该段,而未对齐的访问是最容易发生这种情况的方法。

OP假设x86体系结构无法访问未对齐的数据(地址处的数据不是所用寄存器大小的倍数),这是精简指令集计算(RISC)处理器中的一个常见问题。例如:

mov ebx, 0x12345677    ; Note the odd address
mov eax, [ebx]         ; Load a 32-bit register from an odd address
在RISC架构(如ARM或PowerPC)中,这确实会导致问题:总是(ARM)或如果不禁用(PowerPC)。在x86体系结构中,未对齐的访问始终是可能的(尽管有时会以速度为代价),而且直到486年以后,它才能够被检查;但这张支票几乎总是被拒之门外

事实证明,问题出在其他地方:

mov dword eax, [ebx+esi]; store that pixel's color bytes ; ERROR, SEGSEV
OP没有确认
esi
保持所需的值


不过,请注意,未与x86对齐的访问仍然会导致问题。所有段都定义为特定大小(即使该大小为4GiB)。靠近该段顶部的访问可能会“溢出”该段,而未对齐的访问是最容易发生这种情况的方式。

您不需要将
dword
放在寄存器前面,因为寄存器的大小总是已知的。
mov ebx,loc
loc
的地址移动到ebx。这是您想要的还是您想要
loc
处的值以及类似
mov ebx、[loc]
的值?如果您使用一个调试器(即:gdb)进行调试,您应该确切地了解为什么这个调试器失败
mov
可以很好地访问对齐的数据,这可能会导致性能下降,具体取决于体系结构。大多数x86操作系统不启用对齐检查。但是,由于您正在读取4个字节,而本应只读取3个字节,因此您有可能读取到源映像的末尾,并进入尚未分配的内存。很可能会出现一些问题,但除非您采取具体步骤确保在尝试读取源图像中的最后一个像素时可能会出错。在我的评论中,有一个输入错误“
mov
可以很好地访问对齐的数据”应该是未对齐的主要问题是,这不是一个最小的完整可验证示例,我们不知道您是否正确设置了ESI和EDI,这是在什么环境中?你自己的内核?是保护模式还是真实模式?解决此问题的最佳方法是使用调试器,逐步完成代码,并确保[ebx+esi]是有效地址。如果这段代码是实模式的,您可能会遇到更大的问题。我假设这是32位保护模式代码。如果这确实是一个分段错误,那么它就是Unix(可能是Linux或OS X)。补充我先前的评论;如果你在为图像的每个像素做任何事情,如果你不打算使用SSE或AVX向量,那么花时间在手写asm上通常没有多大意义。(即使在实模式下也是如此;我认为SSE在实模式下工作,但是)您不需要将
dword
放在寄存器前面,因为寄存器的大小总是已知的。
mov ebx,loc
loc
的地址移动到ebx。这是您想要的还是您想要
loc
处的值以及类似
mov ebx、[loc]
的值?如果您使用一个调试器(即:gdb)进行调试,您应该确切地了解为什么这个调试器失败
mov
可以很好地访问对齐的数据,这可能会导致性能下降,具体取决于体系结构。大多数x86操作系统不启用对齐检查。但是,由于您正在读取4个字节,而本应只读取3个字节,因此您有可能读取到源映像的末尾,并进入尚未分配的内存。很可能会出现一些问题,但除非您采取具体步骤确保在尝试读取源图像中的最后一个像素时可能会出错。在我的评论中,有一个输入错误“
mov
可以很好地访问对齐的数据”主要的问题是这不是一个最小的完全可验证的例子,我们