"Ларчик" открывался просто, в одном из include-файлов была "забыта" строчка #define volatile <пусто>..., и как только этот include попал в проект оптимизатор стал с полным основанием убивать не-volatile код.
В качестве примера:
Исходник на C++
template <class THardwareIo> class T16750 : public TUART16x50
{
[...]
__noinline void Halt(int MaxWait_mks = 1000 * 1000) const
{
while((ReadLineStatus() & (LSR_TSRE | LSR_THRE)) != (LSR_TSRE | LSR_THRE) && MaxWait_mks > 0)
{
KeStallExecutionProcessor(25);
MaxWait_mks -= 25;
}
for(int MaxRead = 1024; (ReadLineStatus() & LSR_DR) && MaxRead > 0; MaxRead--)
ReadReceiveBuffer();
ReadLineStatus();
ReadModemStatus()
ReadInterruptIdentRaw();
}
[...]
Код для Memory Mapped I/O
; _this$ = esi
$L17612:
mov eax, [esi]
add eax, 5
mov al, [eax]
and al, 96
cmp al, 96
je $L17613
cmp _MaxWait_mks$[esp-4], 0
jle $L17613
push 25
call __imp__KeStallExecutionProcessor@4
sub _MaxWait_mks$[esp-4], 25
jmp $L17612
$L17613:
mov eax, [esi]
mov ecx, 1024
$L17615:
test BYTE PTR [eax+5], 1
je $L17617
test ecx, ecx
jle $L17617
mov dl, [eax]
dec ecx
jmp $L17615
$L17617:
mov cl, [eax+5]
mov cl, [eax+6]
mov al, [eax+2]
ret 4
Код для Port I/O
; _this$ = eax
push esi
push edi
mov esi, eax
$L17408:
mov edx, [esi]
add edx, 5
in al, dx
and al, 96
cmp al, 96
je $L17409
cmp _MaxWait_mks$[esp+4], 0
jle $L17409
push 25
call __imp__KeStallExecutionProcessor@4
sub _MaxWait_mks$[esp+4], 25
jmp $L17408
$L17409:
mov ecx, [esi]
mov edi, 1024
lea esi, [ecx+5]
$L17411:
mov dx, si
in al, dx
test al, 1
je $L17413
test edi, edi
jle $L17413
mov dx, cx
in al, dx
dec edi
jmp $L17411
$L17413:
lea edx, [ecx+5]
in al, dx
lea edx, [ecx+6]
in al, dx
lea edx, [ecx+2]
pop edi
in al, dx
pop esi
ret 4
---
|