我再次需要 AT&T 组装方面的帮助,我已经将一些数据加载到内存中,如下所示(十六进制和十进制)。
(gdb) x/8xb &buffer_in
0x8049096: 0x03 0x02 0x10 0x27 0xe8 0x03 0x64 0x00
(gdb) x/8db &buffer_in
0x8049096: 3 2 16 39 -24 3 100 0
假设第一个字节 = 数字计数,第二个 = 每个数字长度(以字节为单位),然后我们得到(第一个 * 第二个)字节的数字。对于此示例,3 个数字,每个 2 个字节,第一个数字是 16 39,依此类推。我想添加每个数字,所以在这种情况下,它会将 0x10 + 0xe8(低字节)添加到 result[0],然后将 0x27 + 0x03 添加到 result[1],然后再添加 result[0] = result[0] + 0x64 最后结果 [1] = 结果 [1] + 0x00。
当我将 0x64 添加到已经包含 0xf8 的结果 [0] 时,设置了 CF(进位标志),这当然很好,因为我想在下一个添加结果 [1] 中使用这个进位。但问题是,在下一条 CMP 指令之后(我将在下面的代码中标记它),这个进位标志被清除,所以最终结果是 0x5C2A(当我结合两个字节的结果时)并且应该是 0x5C2B(但是进位标志没有影响由于 cmp 指令而添加)。
%eax - 要求和的数字数量
%ecx - 每个数字的长度(以字节为单位)
%esi - 在循环开始之前指向“真实”数据的第一个字节(在这种情况下为 0x10)
loop1:
movl $0, %ebx
loop2:
leal (%esi, %ebx, 1), %edi
movb (%edi), %dl # %dl contain now next byte to add
adc %dl, result(%ebx) # adding to result
inc %ebx
cmp %ebx, %ecx # this comparsion clears CF flag and that's the problem
JG loop2
leal (%esi, %ecx, 1), %esi
dec %al
cmp $0, %al
JG loop1