背景:
static void StartLoginForm()
{
Form frm = new Form();
frm.ShowDialog();
frm.Focus();//Didn't work for me
frm.Activate();//Also didn't work for me
}
优化级别的GCC 6.1生成此程序集:
$(document).ready(function(){
var url = window.location.href;
$('.dropdown-menu-fw li').removeClass('active');
$('.dropdown-menu-fw li a').filter(function() {
return this.href == url;
}).parent().addClass('active');
$('.dropdown-fw').removeClass('selected open');
$('.dropdown-menu-fw li a[href="'+ url+'"]').closest(".dropdown-fw").addClass('open selected');
// $('.dropdown-menu-fw li a').parentsUntil(".dropdown-fw").addClass('open');
});
这个功能:
-O3
其中 test ecx, ecx
je .L8
xor r8d, r8d
xor eax, eax
.L7:
xor r9d, r9d
add eax, DWORD PTR [rdi+r8*4] ; adding a[i]
setc r9b
add eax, DWORD PTR [rsi+r8*4] ; adding b[i]
mov r11d, eax ; excessive mov (#1)
setc r10b
mov DWORD PTR [rdx+r8*4], r11d ; storing at s[i]
add r8, 1
movzx r10d, r10b
cmp ecx, r8d
lea eax, [r10+r9] ; sorcery (#2)
ja .L7
rep ret
.L8:
xor eax, eax
ret
,limb_t add(
const limb_t *a,
const limb_t *b,
limb_t *s,
int n
) {
limb_t c = 0, t = 0;
for (int i = 0; i < n; ++i) {
t = a[i] + c;
c = t < a[i];
t += b[i];
c += t < b[i];
s[i] = t;
}
return c;
}
和a
是等长b
个肢的整数,以32位单位(四肢,数字)的连续序列存储在内存中Little Endian(也就是说,第一个是最不重要的肢体)。
此函数会添加两个非负加数s
和n
,将总和存储在a
中,并返回进位b
。临时变量s
保存当前的sum limb,并启用c
和t
场景。
正如我从集会中推断的那样,
a == s
寄存器包含b == s
addend的基地址,rdi
寄存器包含a
addend的基地址,rsi
寄存器保存基地址b
,总和,rdx
注册了s
,随身携带和eax
,临时,c
注册保留t
,循环计数器,r8
注册保留i
,加数和总和的长度。 我的第一个问题是:
1。为什么ecx
寄存器中的n
寄存器值的中间存储在将其移动到存储器eax
(当前的总和)之前会发生?
我没有看到r11d
寄存器的任何其他用法,但对于这种过度的存储操作;并且[rdx + r8*4]
指令实际上允许从r11
寄存器移动,为什么不从那里移动值?
我的第二个问题是:
2。这个带有mov
指令和携带值的巫术是什么?
eax
实际计算的是什么? lea
= lea eax, [r10+r9] ; sorcery (#2)
+ lea
?并且,在这种情况下,为什么我们必须使用此r10
指令清除每个循环迭代的高位r9
?
r10
答案 0 :(得分:2)
第一个似乎是“错过优化”的编译器错误。
第二个需要为c
生成t = a[i] + c;
大小dword,并且通过使用不同的方法扩展两个逻辑值来实现这一点,这些方法无疑是奇怪的:
t < a[i];
由xor r9d, r9d
和setc r9b
执行,但t < b[i]
由setc r10b
和movzx r10d, r10b
对执行。它并不是很明显,但这可能有合理的指令调度原因。
添加两个逻辑值是由lea eax, [r10+r9]
完成的,而add
代替cmp
有两个原因。首先,它不会影响标志,因此可以在ja
和whitep.slice(minIndex, minIndex+nbWords)
之间插入标记。其次,它可以在第三个寄存器中产生输出。
另一种可能性是首先添加两个逻辑值,只扩展结果。不确定这是否是更好的方法。此外,一个临时登记就足够了。