相关疑难解决方法(0)

汇编:增加2(或更大数字)而不破坏ADC循环中的CF?

我试图在Windows中测试TDM-GCC 64位汇编中的附加功能.我在前一段时间搜索了资源,我遇到了类似的代码(我做了一些修改,在TDM-GCC中编译它).

typedef struct
{
    int size;
    __uint64_t uints[130];
} BigInteger;

void add(BigInteger *X, BigInteger *Y);   // X += Y
    // %rcx holds address of X, and %rdx holds address of Y apparently.

    // calc.s - assembly file
    .globl add
add:
    movq    8(%rdx), %rax
    addq    %rax, 8(%rcx)
    movq    16(%rdx), %rax
    adcq    %rax, 16(%rcx)
    movq    24(%rdx), %rax
    adcq    %rax, 24(%rcx)
    ...     ...
Run Code Online (Sandbox Code Playgroud)

第一个汇编代码有效.不利的是,只要计算最大尺寸就需要很小的数字.所以我改为检查X和Y的大小并设置一个大小条件的循环,这样如果X和Y不大,它就不会总是添加整个数组.

    ...
// %r13 holds X addr, %r14 holds Y addr.
    addq    $8, %r13   // I have tried  incq …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 bigint extended-precision tdm-gcc

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

JMP指令对8086的工作有何影响?

我知道 8086 有一个 BIU 和一个 EU,这有助于处理器的流水线化。BIU 有一个 6 字节预取队列,用于提取指令指针指向的地址后面的字节。现在,当要执行的指令是跳转到另一个位置的指令时,预取的所有 6 个字节会发生什么情况?它们会被冲掉然后重新加载吗?(这会破坏处理器的流水线效率,不是吗?)

x86 cpu-architecture machine-code x86-16

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

多年前构建的编译器(例如 gcc)如何仍然可以为最近发布的处理器进行编译?

假设我使用编译器:gcc 4.8。还有来自英特尔的处理器,比如说 Skylake 或其他一些奇特的新系列。

检查这个问题:如何查看哪些标志 -march=native 将激活?; 如果我这样做gcc -march=native -E -v - </dev/null 2>&1 | grep cc1,这将为主机(即上述处理器skylake)喷出一些标志。

当 4.8 在 Skylake 处理器发布之前发布时,gcc 如何知道启用禁用的标志?其他较新的处理器系列呢?

因此,下一个问题是将编译器升级到最新的,以便为新的目标处理器准确和最佳地编译?

这个问题并不是真正针对 gcc/intel,我想知道其他人也如何保持处理器和编译器之间的同步。

compiler-construction optimization gcc intel compiler-optimization

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

在 x86_64 中,如果条件为假,32 位 cmov 是否清除最高位?

在 x86 上的 64 位模式下,大多数 32 位算术运算会清除目标寄存器的前 32 位。如果算术运算是“cmov”指令,并且条件为假怎么办?(我看过的参考手册中似乎没有涵盖这种情况)。

assembly x86-64

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

在 ARM 上同步 JIT/自修改代码的缓存

据我了解,编写并随后执行 JIT 或自修改代码的一般、更抽象的过程如下所示。

  • 编写生成的代码,
  • 确保它已刷新且全局可见0
  • 然后确保从中获取的指令将是所写入的指令。

这篇关于 x86 上自修改代码的文章中我可以看出,手动缓存管理显然是没有必要的。我认为 aclflushopt是必要的,但 x86 1显然会在从具有新指令的位置加载时自动处理缓存失效,这样指令提取就永远不会过时。我的问题不是关于 x86,但我想将其包括在内以进行比较。

AArch64 中的情况稍微复杂一些,因为它区分了可共享域以及缓存操作的“可见性”程度。仅从 ARMv8/ARMv9 的官方文档中,我首先得出了这个猜测。

  • 编写生成的代码,
  • dsb ishst确保在继续之前已全部写入,
  • 然后isb sy确保从内存中提取后续指令。

DMB/DSB/ISB 的文档说“ISB 后面的指令是从缓存或内存中获取的”。这给我的印象是缓存控制操作确实是必要的。我的新猜测是这样的。

  • 编写生成的代码,
  • dsb ishst确保在继续之前已全部写入,
  • 然后是ic ivau新代码占用的所有缓存行。

但我又忍不住觉得这也不太对劲。过了一会儿,我在文档中发现了一些我错过的东西,并且在一篇论文中发现了几乎相同的东西。他们都给出了一个看起来像这样的例子。

dc cvau, Xn ; Clean cache to PoU, so the newly written code will be visible
dsb ish     ; Wait for cleaning to finish
ic ivau, Xn ; Invalidate …
Run Code Online (Sandbox Code Playgroud)

assembly self-modifying memory-barriers cpu-cache arm64

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

是否有比cpuid更便宜的序列化指令?

我已经看到了相关的问题,包括这里这里,但似乎有关序列化的唯一指令rdtsccpuid.

不幸的是,cpuid我的系统需要大约1000个周期,所以我想知道是否有人知道更便宜(更少的周期和没有读或写内存)序列化指令?

我看着iret,但这似乎改变了控制流程,这也是不可取的.

我实际上看过亚历克斯的答案中关联的白纸rstscp,但它说:

在读取计数器之前,RDTSCP指令等待直到执行了所有先前的指令.然而,后续指令可以在执行读取操作之前开始执行.

第二点似乎是让它不理想.

intel rdtsc cpu-cache

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

页面遍历是否利用共享表?

假设两个地址空间共享一块较大的非连续内存。系统可能希望在它们之间共享物理页表。这些表不会使用全局位(即使支持),并且如果支持的话会将它们绑定到asid

这样做有直接的好处,因为数据缓存的污染比副本、更少的固定内存等污染要少。

页面遍历是否在任何已知架构中明确利用了这一点?如果是这样,这是否意味着mmu正在根据物理标签显式缓存和共享内部页面树节点?

很抱歉提出了多个问题;这确实是一件坏事。我正在尝试确定是否值得为此设计一个测量测试。

performance cpu-architecture virtual-memory mmu page-tables

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