【发布时间】:2017-05-24 09:01:32
【问题描述】:
我再次需要 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
【问题讨论】:
-
pushf/popf 对你有用吗?例如,在 loop2 标签之前执行 pushf,在它之后执行 popf,然后在 cmp 指令之前再次 pushf。这应该保存/恢复状态(标志)寄存器,从而在 cmp 中保留进位标志..
-
@Sokre 它正在工作,也只是尝试 pushf popf 但您的正确解决方案首先出现!谢谢哥们!
标签: assembly flags att carryflag