Questions tagged «assembly»

汇编语言(asm)编程问题。确保还标记您正在使用的处理器和/或指令集以及汇编器。警告:对于.NET程序集,请使用标签[.net-assembly]。对于Java ASM,请改用标记[java-bytecode-asm]。

2
现代PC视频硬件是否在硬件中支持VGA文本模式,或者BIOS是否模拟了它(使用系统管理模式)?
当您在物理线性地址的VGA文本(模式03)帧缓冲器中存储一个字节(例如(0x31))到VGA文本(模式03)时,在以16位旧式BIOS MBR模式引导的现代PC硬件上究竟发生了什么? 将针对该区域的MTRR设置为UC 的商店有多慢? (在一台Kaby Lake iGPU笔记本电脑上进行的实验测试表明,WC上的clflushopt与VGA内存的UC大致相同。但是,如果没有clflushopt,存储到WC内存中的内存永远不会离开CPU,也根本不会更新屏幕,运行速度非常快)'1'B8000mov [es:di], eaxmov 如果不是每个商店的SMI,是否有任何方法可以在用户空间中的WB内存块上近似估算此成本,以进行性能实验而无需实际重新进入实模式?(例如,使用BSS页面作为假装的帧缓冲区,该缓冲区实际上不会显示在任何地方)。 下次刷新时,相应的字形出现在屏幕上,但是硬件扫描真的从VRAM(或iGPU的DRAM)中读取ASCII字符并动态映射到位图字形吗?还是每个存储上都有某个软件拦截或每个vblank拦截一次,以便真正的硬件仅需要处理位图帧缓冲区? 众所周知,传统BIOS引导使用系统管理模式(SMM)将USB kbd /鼠标模拟为PS / 2设备。我想知道它是否也用于VGA文本模式帧缓冲区。我认为它是用于VGA的I /模式的设置O端口,但它是合理的,文本的framebuffer可以通过硬件来支持。但是,大多数计算机将所有时间都花在图形模式上,因此抛弃对文本模式的硬件支持似乎是厂商可能想要做的事情。(OTOH 该博客建议自制的Verilog VGA控制器可以相当简单地实现文本模式。) 我对在Intel Skylake中使用iGPU的系统特别感兴趣,但对Intel和AMD的早期/以后iGPU以及新旧的离散GPU感兴趣。 (包括AMD和NVidia以外的供应商;有些Skylake主板具有PCI插槽,而不是PCIe。如果现代GPU固件驱动程序确实模拟文本模式,则大概是一些旧的PCI视频卡具有硬件VGA文本模式。也许这样的卡可能使商店仅是PCI事务而不是SMI。) 我自己的台式机是华硕Z170 Pro游戏主板中的i7-6700k,没有附加卡,只有在DVI-D输出上具有1920x1200显示器的iGPU。我不知道Kaby Lake i5-7300HQ系统的详细信息@Eldan仅在CPU型号上进行测试。 我从2011年起发现了Phoenix BIOS的专利US20120159520,它 使用uefi模拟旧版视频。他们不要求视频硬件供应商同时提供UEFI 和本机16位实模式选项ROM驱动程序,而是提出了实模式VGA驱动程序(int 10h功能等),该驱动程序通过SMM挂钩调用供应商提供的UEFI视频驱动程序。 摘要 通用视频选项ROM将视频服务请求通知通用视频SMM驱动程序。可以使用软件系统管理中断(SMI)执行此类通知。收到通知后,通用视频SMM驱动程序会将对视频服务的请求通知第三方UEFI视频驱动程序。第三方视频驱动程序向操作系统提供请求的视频服务。以此方式,第三方UEFI图形驱动程序可以支持多种操作系统,即使不是本机支持UEFI显示协议的操作系统。 许多描述涵盖了处理int 10h呼叫和类似已经明显通过IVT捕获的内容,因此可以轻松地运行自定义代码,从而有意触发SMI。相关部分是它们描述的直接存储到文本模式帧缓冲区中的内容,即使对于不触发任何软件或硬件中断的代码,它们也需要工作。(除了硬件在此类商店上触发SMI之外,他们表示可以在支持的情况下使用它们。) 文字缓冲支持 [0066]在某些实施例中,应用程序可以直接操纵VGA的文本缓冲区。在这样的实施例中,通用视频SMM驱动器130以两种方式中的一种来支持这一点,这取决于硬件是否在对740 KB-768 KB存储区域(文本缓冲区所在的位置)的读/写访问时提供SMI陷阱。 [0067]当SMI陷阱可用时,硬件会在每次读取或写入访问时生成一个SMI。使用SMI陷阱的陷阱地址,可以计算出确切的文本列和行,并访问虚拟文本屏幕中的相应行和列。 可替代地,为该区域启用普通存储器,并且使用周期性的SMI,通用视频SMM驱动器130扫描仿真的硬件文本缓冲器中的变化,并更新由视频驱动器维护的相应虚拟文本屏幕。在两种情况下,当检测到更改时,都会在虚拟文本屏幕上重新绘制字符。 这只是BIOS供应商的一项专利,并没有告诉我们大多数硬件的实际工作方式,或者其他供应商是否做不同的事情。但是,它的确确证了存在某些硬件,这些硬件可能会在该范围内的商店中受困。(除非那只是他们决定在其专利中涵盖的一种假设可能性。) 对于我所想到的用例,仅在屏幕刷新上进行捕获要比在每个商店上进行捕获快得多,因此我很好奇哪种硬件/固件以哪种方式工作。 这个问题的动机 在第7代Intel Core上优化视频RAM中的递增ASCII十进制计数器 -将ASCII文本计数器的新数字重复存储到视频RAM的相同字节中。 我在Linux下的WB内存中的32位用户空间中测试了该代码的版本,希望通过movnti每种存储后(或偶尔在计时器中断)。但是,如果实模式引导加载程序情况不只是存储到DRAM,而是触发SMI,这是不现实的。 在WB内存中,用刷新movnti存储lock xor …

2
L2 HW预取器真的有用吗?
我在Whiskey Lake i7-8565U上,分析性能计数器和复制512 KiB数据的时间(是L2缓存大小的两倍),并且对L2 HW预取器的工作遇到了一些误解。 在英特尔手册第4卷MSR中,有MSR 0x1A4的位0用于控制L2硬件预取器(禁用1)。 考虑以下基准: memcopy.h: void *avx_memcpy_forward_lsls(void *restrict, const void *restrict, size_t); memcopy.S: avx_memcpy_forward_lsls: shr rdx, 0x3 xor rcx, rcx avx_memcpy_forward_loop_lsls: vmovdqa ymm0, [rsi + 8*rcx] vmovdqa [rdi + rcx*8], ymm0 vmovdqa ymm1, [rsi + 8*rcx + 0x20] vmovdqa [rdi + rcx*8 + 0x20], ymm1 add …


2
是什么导致Cortex-A72上带有-O0而不是-O3的简单紧密循环的周期如此高的变化?
我正在围绕获取一段代码的高度一致的运行时进行一些实验。我当前正在计时的代码是一个相当随意的CPU约束工作负载: int cpu_workload_external_O3(){ int x = 0; for(int ind = 0; ind < 12349560; ind++){ x = ((x ^ 0x123) + x * 3) % 123456; } return x; } 我已经编写了一个内核模块,该模块禁用中断,然后运行上述功能的10次尝试,通过获取前后时钟周期计数器的差值来计时每次尝试。其他注意事项: 该机器是ARM​​ Cortex-A72,具有4个插槽,每个插槽具有4个内核(每个插槽都有自己的L1缓存) 时钟频率缩放关闭 不支持超线程 机器几乎没有运行,除了一些简单的系统进程 换句话说,我相信大多数/所有系统可变性的原因都可以解决,尤其是当通过禁用了中断的内核模块运行时spin_lock_irqsave(),代码在运行时应该获得几乎相同的性能(可能对性能造成很小的影响)在第一次运行时,首先将某些指令拉入缓存,仅此而已)。 的确,当使用编译基准测试代码时-O3,我平均看到了大约135,845,192个周期中的最多200个周期,并且大多数测试花费的时间完全相同。但是,当使用编译时-O0,范围从262,710,916上升至158,386个周期。范围是指最长和最短运行时间之间的差。而且,对于-O0代码而言,哪个试验是最慢/最快的试验并没有太多的一致性-违反直觉,在某些情况下,最快的试验是最先的,而最慢的试验是在后的! 那么:是什么原因导致-O0代码的可变性如此高的上限?看一下程序集,似乎-O3代码将所有内容(?)存储在寄存器中,而-O0代码中有很多引用sp,因此似乎正在访问内存。但是即使那样,我也希望所有内容都可以放入L1缓存中,并且在确定的访问时间内就可以坐在那里。 码 被基准测试的代码在上面的代码段中。组件在下面。两者都编译时gcc 7.4.0没有标记,除了-O0和-O3。 -O0 0000000000000000 <cpu_workload_external_O0>: 0: d10043ff sub sp, sp, …
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.