我得到了x86代码,用于添加两个具有comp3类型的数字(参见cobol),添加逻辑非常奇怪且令人困惑但是给出了正确的结果。可以帮助我使用此代码
>>00401229<< add eax,33333333h ; [00 00 01 23] + [33 33 33 33] = [33 33 34 56]eax
0040122E add edx,33333333h ; [00 00 02 20] + [33 33 33 33] = [33 33 35 53]edx
00401234 mov ebx,eax ; copying eax to ebx ; ebx = eax = 33 33 34 56
00401236 xor ebx,edx ; [33 33 34 56] xor [33 33 35 53] = [00 00 01 05](EBX)
00401238 add eax,edx ; [33 33 34 56]eax + [33 33 35 53]edx = [66 66 69 A9]eax
0040123A xor ebx,eax ; [00 00 01 05](ebx) xor [66 66 69 A9](eax) = [66 66 68 AC](ebx)
0040123C shr ebx,3 ; 3 >> [66 66 68 AC](ebx) = [0C CC CD 15](ebx)
0040123F not ebx ; [0C CC CD 15](ebx) NOT ==> [F3 33 32 EA](ebx)
00401241 and ebx,22222222h ; [F3 33 32 EA](ebx) & [22 22 22 22] = [22 22 22 22]
00401247 lea ebx,[ebx+ebx*2] ;ebx = 66 66 66 66
0040124A sub eax,ebx ;[66 66 69 A9]eax - [66 66 66 66]ebx = 343
更多代码可能不相关
004011D1 mov eax,3C120000h // EAX = 3C120000h
004011D6 mov dword ptr [$HELLO.DATA+0D8h (409A08h)],eax // at 409A08h moving data 00 00 12 3c
004011DB mov eax,0C220000h // EAX = 0C220000h
004011E0 mov dword ptr [$HELLO.DATA+0E0h (409A10h)],eax // at 409A10h moving data 00 00 22 0c
004011E5 sub eax,eax // may be clearing eax
004011E7 mov eax,dword ptr [$HELLO.DATA+0D8h (409A08h)] // copying from 409A08h data(00 00 12 3c) to EAX
004011EC bswap eax // eax becomes 00 00 12 3c from 3C 12 00 00h
004011EE sub edx,edx // perhaps clearing edx
004011F0 mov edx,dword ptr [$HELLO.DATA+0E0h (409A10h)] // copying from 409A08h data 00 00 22 0c to EDX
004011F6 bswap edx // edx becomes 00 00 22 0c from 0C 22 00 00
004011F8 mov ebx,eax ....................................// copying from eax to ebx , ebx becomes 00 00 12 3c
004011FA and ebx,0Fh ....................................// ebx & 0Fh,(00 00 12 3c)&(0Fh) => 00 00 00 0C
// extracting sign from value ebx ,storing 'C' in ebx
004011FD mov ch,byte ptr $HELLO.LIT+230h (40E230h)[ebx] // 'ch' refer to 8 to 15 bits of ecx register
// ecx register -> |_15 to 8_| 7 to 0| ,
// byte from ebx is copied to ecx position 8 to 15
00401203 mov ebx,edx // value of edx ( 00 00 22 0C ) copied to ebx
00401205 and ebx,0Fh // extracting sign of second no by preserving last
nibble , now ebx has sign of second no i.e 'C'
00401208 mov cl,byte ptr $HELLO.LIT+230h (40E230h)[ebx] // 'CL' refer to '0 TO 7th' bit of 'E C X'
// Copying last 7 bits of ebx to cl
// ECX Becomes ECX = 8E 19 '0C' '0C'
// contains sign of both var , var1 and var 2
15 to 8 and 7 to 0
0040120E shr eax,4 // shifitng EAX right , removing sign nibble from var1
00401211 shr edx,4 // shifitng EDX right , removing sign nibble from var2
var2 , EDX = 00000220
var1 , EAX = 00000123
00401214 cmp ch,cl // comparing the sign of both number
// Both ch & cl part of ECX
//CMP - If the two values are equal, the Z Flag is set (1) otherwise it is not set (0)
00401216 je $HELLO.CODE+219h (401229h) // if both sign equal jump to '401229h'
//JE and JZ : a conditional jump when ZF (the "zero" flag) is equal to 1.
// var2 , EDX = 00000220
// var1 , EAX = 00000123
答案 0 :(得分:2)
要了解正在发生的事情,请考虑在级别上发生的事情 将2个单位十六进制数加在一起
如果2个十六进制十进制数字的总和加起来&lt; 10;结果与将2位十进制数加在一起完全相同:
x'4' + x'5' = x'9' ~ 9
但如果2位数加起来一个&gt; = 10,我们可以加x'6'来得到十进制等值
x'5' + x'6' = x'B' and x'b' + x'6' = x'11' ~ 5 + 6 = 11
x'8' + x'9' = x'11' and x'11' + x'6' = x'17' ~ 8 + 9 = 17
实际公式(单位数级别)更复杂
if digit1 + digit2 < 10 (x'a')
total = digit1 + digit2 + x'6' - x'6'
else
total = digit1 + digit2 + x'6' - x'0'
十六进制加法可用于使用此公式
进行十进制加法 Number_1 + Number_2 + x'66 66 66 66' - x'hi jk lm no'
h
- &gt; o
中的x'hi jk lm no'
0 或 6 。基本上,如果 Number_1.digit + number_2.digit&gt; = 10 ,那么h
- &gt; o
将 0 否则将 6 。
[00 00 01 23] + [00 00 02 20} + [66 66 66 66] - [66 66 66 66] = [00 00 03 43]
[00 00 07 18] + [00 00 06 28} + [66 66 66 66] - [66 66 06 06] = [00 00 13 46]
[00 00 01 83] + [00 00 02 91} + [66 66 66 66] - [66 66 66 06] = [00 00 04 74]
以下4个陈述(来自前5个)计算: number_1 + Number_2 + x'66 66 66 66'
00401229 add eax,33333333h ; [00 00 01 23] + [33 33 33 33] = [33 33 34 56]eax
0040122E add edx,33333333h ; [00 00 02 20] + [33 33 33 33] = [33 33 35 53]edx
00401234 mov ebx,eax ; copying eax to ebx ; ebx = eax = 33 33 34 56
00401238 add eax,edx ; [33 33 34 56]eax + [33 33 35 53]edx = [66 66 69 A9]eax
最后最后的行也很容易
00401241 and ebx,22222222h ; [F3 33 32 EA](ebx) & [22 22 22 22] = [22 22 22 22]
00401247 lea ebx,[ebx+ebx*2] ;ebx = 66 66 66 66
数字x'6'表示为b'0110',即设置2比特。这更容易 设置/清除1位,即x'2'为b'0010',因此为22222222h。
因此,以下行计算x'hi jk lm no'
/ 3:
00401241 and ebx,22222222h ; [F3 33 32 EA](ebx) & [22 22 22 22] = [22 22 22 22]
并且第二行将(x'hi jk lm no'
/ 3)乘以3给我们x'hi jk lm no'
;在位级别,它将0010转换为0110.
查看前两行
0040123C shr ebx,3 ; 3 >> [66 66 68 AC](ebx) = [0C CC CD 15](ebx)
0040123F not ebx ; [0C CC CD 15](ebx) NOT ==> [F3 33 32 EA](ebx)
右移3将'进位'移回2位(准备和与x'2')。考虑在位级添加2位数:
8 + 9 = b'1000' + b'1001' = b'10001'
接下来我们需要为decimal adjustment
b'10001' + b'0110' = b'10111'
如果你将b'1 0111'3位向右移动你得到b'0010'(x'2'),不将其反转为b'1101' 准备好和到x'22 22 22 22'已经讨论过这一步:
00401241 and ebx,22222222h ; [F3 33 32 EA](ebx) & [22 22 22 22] = [22 22 22 22]
我怀疑代码会丢失顶部进位,所以
[50 00 00 01] + [50 00 00 01]
可能是[A0 00 00 02]而不是[00 00 00 02]。第二部分可以纠正这个???
如果数字以Comp-3开始并且右移4位,则不会出现问题