小编GJ.*_*GJ.的帖子

MOVDQA和MOVAPS x86指令之间的区别?

我正在寻找英特尔数据表:英特尔®64和IA-32架构软件开发人员手册 ,我找不到它们之间的区别

  • MOVDQA:移动对齐双四字
  • MOVAPS:移动对齐打包单精度

在英特尔数据表中,我可以找到两个指令:

该指令可用于从128位存储器位置加载XMM寄存器,将XMM寄存器的内容存储到128位存储器位置,或在两个XMM寄存器之间移动数据.

唯一的区别是:

要将双四字移入或移出未对齐的存储单元,请使用MOVDQU指令.

要将打包的单精度浮点值移入或移出未对齐的内存位置,请使用MOVUPS指令.

但是我找不到两个不同指令的原因?

那么有人可以解释这个区别吗?

x86 assembly sse mov

28
推荐指数
1
解决办法
1万
查看次数

将两个x86 32位寄存器存储到128位xmm寄存器中

有没有更快的方法在一个128位xmm寄存器中存储两个x86 32位寄存器?

  movd  xmm0, edx
  movd  xmm1, eax
  pshufd xmm0, xmm0, $1
  por   xmm0, xmm1 
Run Code Online (Sandbox Code Playgroud)

因此,如果EAX为0x12345678且EDX为0x87654321,则xmm0中的结果必须为0x8765432112345678.

谢谢

x86 assembly sse simd

9
推荐指数
1
解决办法
3100
查看次数

从一个数组中减去另一个数组的最佳方法

我有以下代码,这是我的应用程序的一部分的瓶颈.我所做的就是从另一个数据中减去Array.这两个阵列都有大约100000个元素.我正试图找到一种方法来使这更高效.

var
  Array1, Array2 : array of integer;

..... 
// Code that fills the arrays
.....

for ix := 0 to length(array1)-1
  Array1[ix] := Array1[ix] - Array2[ix];

end;
Run Code Online (Sandbox Code Playgroud)

有人有建议吗?

delphi performance x86 sse

8
推荐指数
3
解决办法
1666
查看次数

如何将两个32位寄存器移入一个64位?

假设我想将两个32位寄存器EAX作为低32位字和EDX高32位字放入RAX.我找到了一种方法:

shl   rdx, 32
or    rax, rdx
Run Code Online (Sandbox Code Playgroud)

只有当我们确定从32到61的位RAX为0时,此方法才有效.如果我们不确定,那么我们必须首先清除高32位字,如:

mov   eax, eax      //This instruction should clear the high 32 bit word of RAX
Run Code Online (Sandbox Code Playgroud)

这是最短路吗?

是否有一个asm x86-64指令执行此操作?

x86 assembly x86-64 move

8
推荐指数
1
解决办法
3162
查看次数

最快的x86汇编代码,用于同步对阵列的访问?

什么是最快的x86汇编代码来同步访问内存中的数组?

更确切地说:我们在内存中有一个malloc'ed连续单页区域,操作系统在我们的实验期间不会将该区域分页.一个线程将写入数组,一个线程将从数组中读取.数组很小,但大于你的cpu的原子写能力(因此需要一个单独的锁)

"最快":有效速度:不要只假设字节码的长度很重要,而是考虑锁的缓存行为和与周围代码有关的分支行为.

它必须在x86-32和/或x86-64上运行

它必须在XP之后(或后代)Windows,Linux自内核2.2或MaxOs X(在用户模式下)工作.

请不要"它取决于" - 回应:如果它取决于我在这里没有指定的任何东西,只需编写你自己的例子,并说明那个/那些情况下最快的.

邮政编码!(这是为了防止模糊的描述)

不仅要发布你的2行LOCK+ CMPXCHG比较和交换,还要告诉我们如何将它与一个线程中的读取指令和另一个线程中的写入指令集成.

如果您愿意,请解释您对缓存最优性的调整,以及如果分支目标依赖于(1)是否获得锁定(2)更大读取的第一个字节是什么,如何避免分支错误预测.

如果你喜欢区分多处理和任务切换:如果线程没有在2个cpus上执行但只是抓住一个线程,你的代码将如何执行?

x86 assembly multithreading

7
推荐指数
1
解决办法
569
查看次数

如何从shl获得大于2 ^ 32的结果?

宣言...

const
  n = 2 shl 33
Run Code Online (Sandbox Code Playgroud)

n在没有编译器投诉的情况下将常数设置为值4!

也...

Caption := IntToStr(2 shl 33);
Run Code Online (Sandbox Code Playgroud)

...返回4而不是8589934592.看起来编译器计算如下:

2 shl 33 = 2 shl(33和$ 1F)= 4

但没有任何警告或溢出.

如果我们声明:

const
  n: int64 = 2 shl 33;
Run Code Online (Sandbox Code Playgroud)

常数中的数字仍然是4而不是8589934592.

任何合理的工作?

delphi 64-bit bit-shift

6
推荐指数
1
解决办法
1356
查看次数

如何从delphi XE2中的绝对地址读取数据

假设我想从gs:$3064位模式的绝对地址读取,所以asm代码看起来像:

asm
  mov   rax, gs:[$30]
end;
Run Code Online (Sandbox Code Playgroud)

...和编译器将此代码翻译为......

  65 48 8B 05 30 00 00 00       mov rax,gs:[rel $00000030]
Run Code Online (Sandbox Code Playgroud)

但我不想使用相对地址(rip + $30).我希望编译器使用绝对地址并以这种方式编译:

  65 48 8B 04 25 30 00 00 00    mov rax,gs:[+$0030]
Run Code Online (Sandbox Code Playgroud)

(如果我使用gs:前缀,它是一样的!)

我该怎么做呢?

编辑:

我知道解决方法.我问是否存在任何命令告诉编译器将位置称为绝对而非相对.

编辑

到现在为止还挺好... :)

drhirsch帮我找到了命令,现在编译器翻译:

mov   rax, gs:[abs qword ptr $30]
or
mov   rax, gs:[abs $30]
Run Code Online (Sandbox Code Playgroud)

对此:

6548A13000000000000000 mov rax,[qword $0000000000000030]
Run Code Online (Sandbox Code Playgroud)

这几乎是好的:)因为我想要短的32位操作码(看上面的操作码)更长的64位操作码.

有没有办法告诉编译器使用短32位地址操作码而不是长?

delphi assembly x86-64 delphi-xe2 basm

6
推荐指数
1
解决办法
739
查看次数

Delphi 10.3 函数 CharUpper 和 CharUpperW 与 Delphi 10.4 不同

CharUpper有人知道 Delphi 10.3 中的声明与CharUpperWDelphi 10.4 中不同的原因吗?

Delphi 10.3 中的正确声明

    var
      chr   :WideChar;
    begin      
      chr := WideChar(CharUpperW(PWideChar('a'))); //chr = 'A'
//    chr := WideChar(CharUpperW(WideChar('a')));  //raise exeption: "access violation...
Run Code Online (Sandbox Code Playgroud)

Delphi 10.4 中的正确声明

    var
      chr   :WideChar;
    begin   
//    chr := WideChar(CharUpperW(PWideChar('a')));  //raise exeption: "access violation...
      chr := WideChar(CharUpperW(WideChar('a')));   //chr = 'A'
Run Code Online (Sandbox Code Playgroud)

编辑:Remy Lebeau 对 PWideChar 的解释是正确的,但 Delphi 10.4 版和更早版本仍然存在差异!

Lebeau解释代码示例在10.4版本及更早版本中编译,但函数的输出不同。10.4 之前的所有版本都得到正确的输出“A”!

var
  char , chr : WideChar;
begin
  chr := 'a';
  char := WideChar(CharUpperW(PWideChar(chr)));
end;
Run Code Online (Sandbox Code Playgroud)

10.4 下的此示例无法正常工作,输出是随机字符。

当然...函数的声明 …

delphi

5
推荐指数
1
解决办法
538
查看次数

如何使固定长度的Delphi字符串使用宽字符?

在Delphi 2010下(也可能在D2009下),默认字符串类型是UnicodeString.

但是,如果我们宣布......

const
 s  :string = 'Test';
 ss :string[4] = 'Test';
Run Code Online (Sandbox Code Playgroud)

...然后第一个字符串s如果声明为UnicodeString,但第二个ss声明为AnsiString!

我们可以检查一下:SizeOf(s[1]);将返回大小2和SizeOf(ss[1]); 将返回大小1.

如果我宣布......

var
  s  :string;
  ss :string[4];
Run Code Online (Sandbox Code Playgroud)

...比我想要的ss也是UnicodeString类型.

  1. 我怎样才能告诉Delphi 2010这两个字符串应该是UnicodeString类型?
  2. 我怎么能宣布ss拥有四个WideChars?编译器不接受类型声明WideString[4]UnicodeString[4].
  3. 两个不同的编译器声明对于相同类型名称的目的是什么:string

delphi unicode-string widestring delphi-2010

3
推荐指数
1
解决办法
3265
查看次数

使用"for in"语句和编译器错误E2064

我想用句子中的下D2010我的测试案例.

如果我想写Param.Value变量然后编译器报告错误2064,但允许从同一记录写入Param.Edit.text,为什么?

测试用例:

type
//
  TparamSet = (param_A, param_B, param_C, param_D, param_E, param_F);

  TParam = record
    Edit        :TEdit;
    Value       :integer;
  end;

var
  dtcp                  :array [TparamSet] of TParam;

procedure ResetParams;
var
  Param                 :TParam;
  A                     :Integer;
begin
  for Param in dtcp do
  begin
    Param.Edit.text:= 'Test';             //No problem
    A := Param.Value;                     //No problem
    Param.Value := 0;                     //Error: E2064 Left side cannot be assigned to;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

delphi delphi-2010 for-in-loop

3
推荐指数
1
解决办法
547
查看次数