我正在研究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整除的位置(例如:像素1:0.B,1.G,2.R;像素2:3.B,4.G,5.R - 所以我必须访问地址3才能到达第二个像素) 的
问题是:如果我不允许访问未对齐的内存位置,那么如何访问像素的数据?在使用bmp文件时通常如何进行?
答案 0 :(得分:0)
OP假设x86架构无法访问未对齐数据(地址不是所用寄存器大小的倍数),这是精简指令集计算(RISC)处理器中的常见问题。例如:
mov ebx, 0x12345677 ; Note the odd address
mov eax, [ebx] ; Load a 32-bit register from an odd address
在像ARM或PowerPC这样的RISC架构中,这确实会导致问题:始终(ARM)或未禁用(PowerPC)。使用x86架构时,一直都可以进行未对齐的访问(虽然有时会受到速度限制) - 并且只有在486以后它才能被检查;但这项检查几乎总是关闭。
事实证明问题出在其他地方:
mov dword eax, [ebx+esi]; store that pixel's color bytes ; ERROR, SEGSEV
OP尚未确认esi
保持所需的值。
但请注意,使用x86进行未对齐访问仍可能导致问题。所有段都定义为特定大小(即使该大小为4GiB)。靠近该段顶部的访问可以"溢出"段 - 和未对齐的访问是最容易受到影响的方法。