相关疑难解决方法(0)

向整数寄存器的每个位置重复/广播一个字节

我正在努力解决汇编中的问题,我必须获取十六进制代码的第一个字节 (FF) 并将其复制到整个值上:

0x045893FF      input
0xFFFFFFFF      output
Run Code Online (Sandbox Code Playgroud)

我所做的是:

movl $0x04580393FF, %eax
shl $24, %eax     # to get only the last byte 0xFF000000
Run Code Online (Sandbox Code Playgroud)

现在我想将此字节复制到寄存器的其余部分。

x86 assembly bit-manipulation

2
推荐指数
1
解决办法
1283
查看次数

如何将(最多)16个单字节移入XMM寄存器?

我有一个归零的128位寄存器,我想向左移位并添加一个字节.我可以改为:

pslldq xmm0, 1 
Run Code Online (Sandbox Code Playgroud)

......但是现在我想将al复制到空白区域.就像是:

or xmm0, al
Run Code Online (Sandbox Code Playgroud)

这当然不起作用.我只希望受影响的最低8位.这将是一个循环,其中al的连续值将用于填充寄存器.所以我需要一些mov指令或其他替代方案.

理想的是单个指令向左移8位并插入,但我不认为存在这样的指令.

我花了很多时间在x86-64指令集数据中翻找,但找不到任何可以让我做我想做的事情.可以吗?

更新:尝试使用pinsrb后,我在代码逻辑中发现了一个错误.pinsrb会很棒但不幸的是它只能使用立即索引而不是寄存器.

我从非连续位置获取字节,所以我认为我需要一次一个字节.字节数可以是1到16之间的任何字节.我抓取的第一个字节应该以xmm0的最低字节结束,下一个字节进入下一个最低字节等.

x86 assembly sse intel simd

2
推荐指数
1
解决办法
1426
查看次数

在 64 位 x64/Amd64 处理器上执行 8 位和 64 位指令的时序

当 8 位指令和 64 位 x64/Amd64 处理器上的 64 位指令除了位宽之外相似/相同时,这些指令之间是否存在执行时序差异?有没有办法找到执行这两个微小汇编函数的真实处理器时序?

-谢谢。

; 64 bit instructions
add64:
     mov  $0x1, %rax
     add  $0x2, %rax
     ret

; 8 bit instructions
add8:
     mov  $0x1, %al
     add  $0x2, %al
     ret
Run Code Online (Sandbox Code Playgroud)

performance 64-bit assembly x86-64 micro-optimization

2
推荐指数
1
解决办法
489
查看次数

有什么方法可以使用 MOV 在 32 位 x86 中移动 2 个字节而不会导致模式切换或 CPU 停顿?

如果我想将 2 个无符号字节从内存移动到 32 位寄存器中,我可以用MOV指令而不用模式切换来做到这一点吗?

我注意到您可以使用MOVSEMOVZE说明来做到这一点。例如,通过MOVSE编码0F B7将 16 位移动到 32 位寄存器。不过,它是一个 3 周期指令。

或者,我想我可以将 4 个字节移动到寄存器中,然后以某种方式仅 CMP 中的两个。

在 32 位 x86 上检索和比较 16 位数据的最快策略是什么?请注意,我主要进行 32 位操作,因此我无法切换到 16 位模式并留在那里。


仅供初学者参考:这里的问题是 32 位 Intel x86 处理器可以处理MOV8 位数据和 16 位 OR 32 位数据,具体取决于它们所处的模式。这种模式称为“D 位”设置。您可以使用特殊前缀 0x66 和 0x67 来使用非默认模式。例如,如果您处于 32 位模式,并且您使用 0x66 作为指令前缀,这将导致操作数被视为 16 位。唯一的问题是这样做会导致性能下降。

performance x86 assembly intel

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

Delphi - 用函数编写.pas库

我正在使用Assembly在Delphi中编写一些函数.所以我想把它放在一个名为的.pas文件中Strings.pas.用于uses新的Delphi软件.我需要写什么才能使它成为一个有效的库?
我的功能是这样的:

function Strlen(texto : string) : integer;
begin
  asm
    mov esi, texto
    xor ecx,ecx
    cld
    @here:
    inc ecx
    lodsb
    cmp al,0
    jne @here
    dec ecx
    mov Result,ecx
  end;
end;
Run Code Online (Sandbox Code Playgroud)

这会计算字符串中字符的数量.如何在lib中创建它Strings.pasuses Strings;在我的表单中调用?

delphi assembly function

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

BITWISE AND操作如何在C程序中占用比ARITHMETIC ADDITION操作更多的CPU时钟?

我想测试按位运算是否真的比算术运算更快.我以为他们是.

我写了一个小的C程序来测试这个假设,令我惊讶的是,加法平均比按位AND运算少.这对我来说是令人惊讶的,我无法理解为什么会这样.

根据我所知的附加,来自较低有效位的进位应该被携带到下一位,因为结果也取决于进位.对我来说逻辑运算符比加法更慢是没有意义的.

我的鳕鱼在下面:

#include<stdio.h>
#include<time.h>

int main() 
{
   int x=10;
   int y=25;
   int z=x+y;
   printf("Sum of x+y = %i", z);
   time_t start = clock();
   for(int i=0;i<100000;i++)z=x+y;
   time_t stop = clock();

   printf("\n\nArithmetic instructions take: %d",stop-start);
   start = clock();
   for(int i=0;i<100000;i++)z=x&y;
   stop = clock();

   printf("\n\nLogic instructions take: %d",stop-start);
}
Run Code Online (Sandbox Code Playgroud)

一些结果:

Arithmetic instructions take: 327
Logic instructions take: 360

Arithmetic instructions take: 271
Logic instructions take: 271

Arithmetic instructions take: 287
Logic instructions take: 294

Arithmetic instructions take: 279
Logic instructions take: …
Run Code Online (Sandbox Code Playgroud)

c assembly instructions logical-operators integer-arithmetic

1
推荐指数
2
解决办法
504
查看次数

在流水线操作时,你可以连续将mov写入同一个寄存器,还是需要3个NOP,比如add?

这是在合并流水线和您需要的必要NOP时实现mov和通过x86添加的正确方法.

 mov $10, eax
 NOP 
 NOP
 NOP
 add $2, eax
Run Code Online (Sandbox Code Playgroud)

如果我想用mov更改eax,我可以立即用另一个mov覆盖它,因为你只是覆盖已经存在的内容,或者我是否需要再次写3个NOP才能完成WMEDF循环?

mov $10, eax
mov $12, eax
Run Code Online (Sandbox Code Playgroud)

要么

mov $10, eax
NOP
NOP
NOP
mov $12, eax
Run Code Online (Sandbox Code Playgroud)

x86 assembly cpu-architecture

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

如何计算 i386 中字符串中某个字符的出现次数?

我是 80386 汇编语言的新手。目前正在努力完成一项学校作业,要求用汇编语言编写一个将在 ac 程序中调用的函数。

extern int count(char *string, char c);

我想我知道应该如何做到这一点,但仍在努力选择正确的指令(指令以“b”、“w”或“l”结尾),也许还有“正确”的寄存器,我知道有一些为某些目的而保留的。

.text
.global count

count:
    pushl   %ebp        # set up stack frame
    movl    %esp,%ebp   # save %esp in %ebp
    subl    $12, %esp   # automatic variables
    movl    $0, %eax    # initialize %eax to 0
    movl    8(%ebp), %esi   # pointer to s
    movb    12(%ebp), %bh   # pointer to c

check:
    movb    (%esi), %bl # move the first char in s to %bl
    cmp     0, %bl      # if the char is \0 …
Run Code Online (Sandbox Code Playgroud)

x86 assembly i386

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

如何在 AVX 寄存器上打包 16 个 16 位寄存器/变量

我使用内联汇编,我的代码是这样的:

__m128i inl = _mm256_castsi256_si128(in);
__m128i inh = _mm256_extractf128_si256(in, 1); 
__m128i outl, outh;
__asm__(
    "vmovq %2, %%rax                        \n\t"
    "movzwl %%ax, %%ecx                     \n\t"
    "shr $16, %%rax                         \n\t"
    "movzwl %%ax, %%edx                     \n\t"
    "movzwl s16(%%ecx, %%ecx), %%ecx        \n\t"
    "movzwl s16(%%edx, %%edx), %%edx        \n\t"
    "xorw %4, %%cx                          \n\t"
    "xorw %4, %%dx                          \n\t"
    "rolw $7, %%cx                          \n\t"
    "rolw $7, %%dx                          \n\t"
    "movzwl s16(%%ecx, %%ecx), %%ecx        \n\t"
    "movzwl s16(%%edx, %%edx), %%edx        \n\t"
    "pxor %0, %0                            \n\t"
    "vpinsrw $0, %%ecx, %0, %0              \n\t"
    "vpinsrw $1, %%edx, %0, …
Run Code Online (Sandbox Code Playgroud)

x86 assembly sse avx

0
推荐指数
1
解决办法
1081
查看次数

使用RSI/RDI vs r8-r15(速度优化)

我想尽可能地优化我的函数,我做的一件事就是使用r8作为指针,因为这是指针在x64函数中被推入的寄存器.

但是推送RSI或RDI,将指针移动到它们并在循环中更快地使用它们?

例如,mov [RSI],DL;将编译为2个字节和:mov [r8],DL; 将编译为3个字节

所以,如果我做了100到200次循环,r8会因为要解码的额外字节而变慢吗?或推动RSI并移动指针消除任何可能的速度增加?显然push和mov会在循环外发生.

optimization assembly x86-64 masm micro-optimization

0
推荐指数
1
解决办法
129
查看次数

将四个 1 字节变量连接成一个 4 字节字时,哪种移位和 OR 方法更快?(比较生成的汇编代码)

因此,我目前正在研究按位运算符和位操作,并且遇到了两种不同的方法将四个 1 字节字组合成一个 4 字节宽字。

下面给出了两种方式

找到这两种方法后,我比较了两者生成的反汇编代码(使用带 -O2 标志的 gcc 11 编译),我没有反汇编及其生成的代码的基本知识,我只知道代码越短,函数速度越快(大多数时候我猜......也许有一些例外),现在对于这两种方法来说,它们在生成的反汇编代码中似乎具有相同的行数/行数,所以我猜他们的表现是一样的?

我也对指令的顺序感到好奇,第一种方法似乎交替其他指令sal>or>sal>or>sal>or,而第二种方法更统一,sal>sal>sal>or>or>mov>or这对性能是否有一些重大影响,例如,如果我们正在处理更大的单词?


两种方法

int method1(unsigned char byte4, unsigned char byte3, unsigned char byte2, unsigned char byte1)
{
    int combine = 0;
    combine = byte4;
    combine <<=8;
    combine |= byte3;
    combine <<=8;
    combine |= byte2;
    combine <<=8;
    combine |= byte1;
    return combine;
}

int method2(unsigned char byte4, unsigned char byte3, unsigned char byte2, unsigned char byte1)
{
    int combine = 0, temp;
    temp = byte4;
    temp …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly bit-manipulation micro-optimization

0
推荐指数
1
解决办法
488
查看次数

x86帮助旋转有效位

x是存储在ebx中的一些整数...如何将4个最高有效位旋转1,同时保留4个最低有效位?其中0xABCDEF12旋转到0xDABCEF12

x86 assembly

-1
推荐指数
1
解决办法
217
查看次数