-1

我正在尝试将 XMM 寄存器存储到某个位置,例如地址行 4534342。

例子:

我做了什么?

我知道 xmm 寄存器包含 128 位值。所以,我的程序已经分配了 16 字节的内存。此外,由于寄存器是对齐的数据,我分配了 31 个字节,然后在其中找到了对齐的地址。这应该可以防止抛出任何异常。

我想在视觉上做什么?

Mem Adr | Contents (binary)
4534342 | 0000 0000 0000 0000  ; I want to pass in address 4534342 and the
4534346 | 0000 0000 0000 0000  ; the program inline-assembly will store it 
4534348 | 0000 0000 0000 0000  ; its contents straight down to address 45-
4534350 | 0000 0000 0000 0000  ; 34350
4534352 | 0000 0000 0000 0000
4534354 | 0000 0000 0000 0000
4534356 | 0000 0000 0000 0000
4534358 | 0000 0000 0000 0000

设置

cyg_uint8 *start_value;      //pointer to the first value of the allocated block                    
cyg_uint32 end_address;      //aligned address location value
cyg_uint32 *aligned_value;   //pointer to the value at the end_address
start_value = xmm_container; //get the pointer to the allocated block
end_address = (((unsigned int) start_value) + 0x0000001f) & 0xFFFFFFF8; //find aligned memory
aligned_value =  ((cyg_uint32*)end_address);  //create a pointer to get the first value of the block

在程序集调用之前调试语句以确保功能

printf("aligned_value: %d\n", (cyg_uint32) aligned_value); printf("*aligned_value: %d\n", *aligned_value);

大会召集

__asm__("movdqa %%xmm0, %0\n" : "=m"(*aligned_value)); //assembly call

在程序集调用之后调试语句以确保功能

printf("aligned_value: %d\n", (cyg_uint32) aligned_value);
printf("*aligned_value: %d\n", *aligned_value);

printf [FAILURE] 的输出

对齐值:1661836 //看起来不错!

*aligned_value: 0 //看起来不错!

aligned_value: -1 //看起来不对 :(

//然后程序卡住了

基本上,我是否正确地执行了这个过程?为什么你认为它会卡住?

感谢您的时间和精力。

4

1 回答 1

4

如果您想要一个 16 字节对齐的地址,我认为您的对齐逻辑不正确。

只需做数学,这很容易!:

(0 + 0x1f) & 0xFFFFFFF8 = 0x18 ; 0x18-0=0x18 未使用字节,0x1F-0x18=7 字节剩余
(1 + 0x1f) & 0xFFFFFFF8 = 0x20 ; 0x20-1=0x1F 未使用字节,0x1F-0x1F=0 字节剩余
...
(8 + 0x1f) & 0xFFFFFFF8 = 0x20 ; 0x20-8=0x18 未使用字节,0x1F-0x18=剩余 7 字节
(9 + 0x1f) & 0xFFFFFFF8 = 0x28 ;0x28-9=0x1F 未使用字节,0x1F-0x1F=0 字节剩余
...
(0xF + 0x1f) & 0xFFFFFFF8 = 0x28 ; 0x28-0xF=0x19 未使用字节,0x1F-0x19=6 字节剩余
(0x10 + 0x1f) & 0xFFFFFFF8 = 0x28 ; 0x28-0x10=0x18 未使用的字节,0x1F-0x18=剩下 7 个字节
(0x11 + 0x1f) & 0xFFFFFFF8 = 0x30 ;0x30-0x11=0x1F 未使用字节,0x1F-0x1F=0 字节剩余
...
(0x18 + 0x1f) & 0xFFFFFFF8 = 0x30 ; 0x30-0x18=0x18 未使用字节,0x1F-0x18=7 字节
(0x19 + 0x1f) & 0xFFFFFFF8 = 0x38 ; 0x38-0x19=0x1F 未使用字节,0x1F-0x1F=0 字节剩余
...
(0x1F + 0x1f) & 0xFFFFFFF8 = 0x38 ; 0x38-0x1F=0x19 未使用字节,0x1F-0x19=6 字节

首先,要使 4 个最低有效位全为零,掩码应为 0xFFFFFFF0。

接下来,如果以这种方式计算对齐地址,则会溢出 31 字节缓冲区。您的数学计算为您留下 0 到 7 个字节的空间,这不足以存储 16 个字节。

为了正确的 16 字节对齐,您应该这样写:

end_address = (((unsigned int)start_value) + 0xF) & 0xFFFFFFF0;

于 2012-07-11T20:59:44.463 回答