Думаю, что это очень накладно. Есть легче способы. Я предложил один из них.
Вид для печати
В таком случае программа точной имитации 32-разрядного сложения может выглядеть так:
MOV #<NOP>,SETPSW
CLR Cflag
CLR Vflag
CLR Zflag
ADD L1,L2
BNE 1$
BIS #4,Zflag
1$:
ADC H2
BVC 2$
BIS #2,Vflag
2$:
ADC Cflag
ADD H1,H2
BMI 3$
BNE 4$
BVC 5$
BIS #2,SETPSW
5$:
BR DONE
3$:
BVC 6$
BIS #2,SETPSW
6$:
BIS #10,SETPSW
BR 7$
4$:
BVC 7$
BIS #2,SETPSW
7$:
BIC #4,Zflag
DONE:
ADC SETPSW
BIS Cflag,SETPSW
ADD Vflag,SETPSW
BIC #4,SETPSW
BIS Zflag,SETPSW
CCC
SETPSW:
NOP
Для проверки правильности работы программы имитации 32-разрядного сложения - добавил в эмулятор команду Add32, выполняющую прибавление 32-разрядного числа с адресом в R0 к 32-разрядному числу с адресом в R1:
В приложении - программа тестирования.Код:if( nWord == 040 )
{ // Add_32_32 -- Add32 (R0),(R1)
word addr00 = R0 &(~1);
word addr02 = addr00 + 2;
dword src = WORD(addr02);
src <<= 16;
src |= WORD(addr00);
word addr10 = R1 &(~1);
word addr12 = addr10 + 2;
dword dst = WORD(addr12);
dst <<= 16;
dst |= WORD(addr10);
word flags;
__asm {
mov EAX, dst
add EAX, src
pushf
mov dst, EAX
pop AX
mov flags,AX
}
WORD(addr10) = (word)dst;
WORD(addr12) = (word)(dst>>16);
PSW &= ~(N|Z|V|C);
if( flags & BIT_0 ) { PSW |= C; }
if( flags & BIT_11 ) { PSW |= V; }
if( flags & BIT_6 ) { PSW |= Z; }
if( flags & BIT_7 ) { PSW |= N; }
continue;
}
Результат запуска:
Вроде, всё правильно.Код:.RU ADD32
Add32 Test v1.0
******************************
SRC: 0x0000'0000 (0)
DST: 0x0000'0000 (0)
Add32 : 0x0000'0000 (0) ; PSW: 004 : N[0] Z[1] V[0] C[0]
$Add32 : 0x0000'0000 (0) ; PSW: 004 : N[0] Z[1] V[0] C[0]
******************************
SRC: 0x0000'0001 (1)
DST: 0x0000'0000 (0)
Add32 : 0x0000'0001 (1) ; PSW: 000 : N[0] Z[0] V[0] C[0]
$Add32 : 0x0000'0001 (1) ; PSW: 000 : N[0] Z[0] V[0] C[0]
******************************
SRC: 0x0000'0001 (1)
DST: 0x0000'0001 (1)
Add32 : 0x0000'0002 (2) ; PSW: 000 : N[0] Z[0] V[0] C[0]
$Add32 : 0x0000'0002 (2) ; PSW: 000 : N[0] Z[0] V[0] C[0]
******************************
SRC: 0x0000'0001 (1)
DST: 0xFFFF'FFFF (-1)
Add32 : 0x0000'0000 (0) ; PSW: 005 : N[0] Z[1] V[0] C[1]
$Add32 : 0x0000'0000 (0) ; PSW: 005 : N[0] Z[1] V[0] C[1]
******************************
SRC: 0x0000'0002 (2)
DST: 0xFFFF'FFFF (-1)
Add32 : 0x0000'0001 (1) ; PSW: 001 : N[0] Z[0] V[0] C[1]
$Add32 : 0x0000'0001 (1) ; PSW: 001 : N[0] Z[0] V[0] C[1]
******************************
SRC: 0xFFFF'FFFF (-1)
DST: 0x0000'0001 (1)
Add32 : 0x0000'0000 (0) ; PSW: 005 : N[0] Z[1] V[0] C[1]
$Add32 : 0x0000'0000 (0) ; PSW: 005 : N[0] Z[1] V[0] C[1]
******************************
SRC: 0xFFFF'FFFF (-1)
DST: 0xFFFF'FFFF (-1)
Add32 : 0xFFFF'FFFE (-2) ; PSW: 011 : N[1] Z[0] V[0] C[1]
$Add32 : 0xFFFF'FFFE (-2) ; PSW: 011 : N[1] Z[0] V[0] C[1]
******************************
SRC: 0x7FFF'FFFF (2'147'483'647)
DST: 0x8001'0001 (-2'147'418'111)
Add32 : 0x0001'0000 (65'536) ; PSW: 001 : N[0] Z[0] V[0] C[1]
$Add32 : 0x0001'0000 (65'536) ; PSW: 001 : N[0] Z[0] V[0] C[1]
******************************
SRC: 0x8001'0001 (-2'147'418'111)
DST: 0x7FFF'FFFF (2'147'483'647)
Add32 : 0x0001'0000 (65'536) ; PSW: 001 : N[0] Z[0] V[0] C[1]
$Add32 : 0x0001'0000 (65'536) ; PSW: 001 : N[0] Z[0] V[0] C[1]
******************************
SRC: 0x0000'0001 (1)
DST: 0x7FFF'FFFE (2'147'483'646)
Add32 : 0x7FFF'FFFF (2'147'483'647) ; PSW: 000 : N[0] Z[0] V[0] C[0]
$Add32 : 0x7FFF'FFFF (2'147'483'647) ; PSW: 000 : N[0] Z[0] V[0] C[0]
******************************
SRC: 0x0000'0001 (1)
DST: 0x7FFF'FFFF (2'147'483'647)
Add32 : 0x8000'0000 (-2'147'483'648) ; PSW: 012 : N[1] Z[0] V[1] C[0]
$Add32 : 0x8000'0000 (-2'147'483'648) ; PSW: 012 : N[1] Z[0] V[1] C[0]
******************************
SRC: 0xFFFF'FFFF (-1)
DST: 0x8000'0001 (-2'147'483'647)
Add32 : 0x8000'0000 (-2'147'483'648) ; PSW: 011 : N[1] Z[0] V[0] C[1]
$Add32 : 0x8000'0000 (-2'147'483'648) ; PSW: 011 : N[1] Z[0] V[0] C[1]
******************************
SRC: 0xFFFF'FFFF (-1)
DST: 0x8000'0000 (-2'147'483'648)
Add32 : 0x7FFF'FFFF (2'147'483'647) ; PSW: 003 : N[0] Z[0] V[1] C[1]
$Add32 : 0x7FFF'FFFF (2'147'483'647) ; PSW: 003 : N[0] Z[0] V[1] C[1]
******************************
Есть ещё какие-то граничные случаи, которые нужно протестировать дополнительно ?
Проверил ещё немного входных данных:
Ошибок нет:Код:.W3232 0000 8000 7fff 8000
.W3232 0002 0000 7ffe 0000
.W3232 0001 0000 7ffe 0000
.W3232 0001 8000 7ffe 8000
.W3232 7fff 0000 7fff 0000
.W3232 8000 0000 7fff 0000
.W3232 8001 0001 7fff ffff
.W3232 7fff ffff 8001 0001
.W3232 8000 0000 8000 0000
.W3232 ffff 0000 8000 0000
.W3232 ffff 8000 8000 8000
Код:.RU ADD32
Add32 Test v1.1
******************************
SRC: 0x0000'8000 (32'768)
DST: 0x7FFF'8000 (2'147'450'880)
Add32 : 0x8000'0000 (-2'147'483'648) ; PSW: 012 : N[1] Z[0] V[1] C[0]
$Add32 : 0x8000'0000 (-2'147'483'648) ; PSW: 012 : N[1] Z[0] V[1] C[0]
******************************
SRC: 0x0002'0000 (131'072)
DST: 0x7FFE'0000 (2'147'352'576)
Add32 : 0x8000'0000 (-2'147'483'648) ; PSW: 012 : N[1] Z[0] V[1] C[0]
$Add32 : 0x8000'0000 (-2'147'483'648) ; PSW: 012 : N[1] Z[0] V[1] C[0]
******************************
SRC: 0x0001'0000 (65'536)
DST: 0x7FFE'0000 (2'147'352'576)
Add32 : 0x7FFF'0000 (2'147'418'112) ; PSW: 000 : N[0] Z[0] V[0] C[0]
$Add32 : 0x7FFF'0000 (2'147'418'112) ; PSW: 000 : N[0] Z[0] V[0] C[0]
******************************
SRC: 0x0001'8000 (98'304)
DST: 0x7FFE'8000 (2'147'385'344)
Add32 : 0x8000'0000 (-2'147'483'648) ; PSW: 012 : N[1] Z[0] V[1] C[0]
$Add32 : 0x8000'0000 (-2'147'483'648) ; PSW: 012 : N[1] Z[0] V[1] C[0]
******************************
SRC: 0x7FFF'0000 (2'147'418'112)
DST: 0x7FFF'0000 (2'147'418'112)
Add32 : 0xFFFE'0000 (-131'072) ; PSW: 012 : N[1] Z[0] V[1] C[0]
$Add32 : 0xFFFE'0000 (-131'072) ; PSW: 012 : N[1] Z[0] V[1] C[0]
******************************
SRC: 0x8000'0000 (-2'147'483'648)
DST: 0x7FFF'0000 (2'147'418'112)
Add32 : 0xFFFF'0000 (-65'536) ; PSW: 010 : N[1] Z[0] V[0] C[0]
$Add32 : 0xFFFF'0000 (-65'536) ; PSW: 010 : N[1] Z[0] V[0] C[0]
******************************
SRC: 0x8001'0001 (-2'147'418'111)
DST: 0x7FFF'FFFF (2'147'483'647)
Add32 : 0x0001'0000 (65'536) ; PSW: 001 : N[0] Z[0] V[0] C[1]
$Add32 : 0x0001'0000 (65'536) ; PSW: 001 : N[0] Z[0] V[0] C[1]
******************************
SRC: 0x7FFF'FFFF (2'147'483'647)
DST: 0x8001'0001 (-2'147'418'111)
Add32 : 0x0001'0000 (65'536) ; PSW: 001 : N[0] Z[0] V[0] C[1]
$Add32 : 0x0001'0000 (65'536) ; PSW: 001 : N[0] Z[0] V[0] C[1]
******************************
SRC: 0x8000'0000 (-2'147'483'648)
DST: 0x8000'0000 (-2'147'483'648)
Add32 : 0x0000'0000 (0) ; PSW: 007 : N[0] Z[1] V[1] C[1]
$Add32 : 0x0000'0000 (0) ; PSW: 007 : N[0] Z[1] V[1] C[1]
******************************
SRC: 0xFFFF'0000 (-65'536)
DST: 0x8000'0000 (-2'147'483'648)
Add32 : 0x7FFF'0000 (2'147'418'112) ; PSW: 003 : N[0] Z[0] V[1] C[1]
$Add32 : 0x7FFF'0000 (2'147'418'112) ; PSW: 003 : N[0] Z[0] V[1] C[1]
******************************
SRC: 0xFFFF'8000 (-32'768)
DST: 0x8000'8000 (-2'147'450'880)
Add32 : 0x8000'0000 (-2'147'483'648) ; PSW: 011 : N[1] Z[0] V[0] C[1]
$Add32 : 0x8000'0000 (-2'147'483'648) ; PSW: 011 : N[1] Z[0] V[0] C[1]
******************************