先讲讲问题所在
调用eth_send函数,具体send是下面这段代码
for (i = 0; i < tmplen; i++)
DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA);
每次我send 08 06 00 01的时候,抓包工具就会抓到08 08 06 06 00 00 01 01这样的数据
也就是每个字节重复了一次
从没想过这条简单地给u16* 赋值的语句会有问题,倒是在其他方面找了几天,没有结果
好在今天想到要不看看汇编代码有啥区别,google一下通过给gcc加-S 选项可以得到汇编结果
说干就干 终于发现 OK的语句 和不行的语句差别是,一个用了STRH ,一个用两条STRB指令 来给DM9000_DATA这个地址赋值
而我们这是给DM9000_DATA这个地址一次传送16bit的数据,编译成STRB显然是曲解了我们的意思,难怪收包会重复一次,原来是分解
成两条指令了
那怎么纠正过来呢,又是一阵google,终于发现是要加-march=armv4来搞定,终于舒了一口气。
附,两个语言对比
[OK的]
mov r3, #536870916
.loc 1 395 0
cmp r4, r5
.loc 1 396 0
strh r2, [r3, #0] @ movhi
b .L110
[错误的]
mov r3, #536870916
ldr r2, [fp, #-36]
mov r1, r2
mov r2, r1, asl #1
ldr r1, [fp, #-28]
add r2, r2, r1
mov r1, r2
ldrb r2, [r1, #0] @ zero_extendqisi2
ldrb r1, [r1, #1] @ zero_extendqisi2
orr r2, r2, r1, asl #8
mov r1, r2 @ movhi
strb r1, [r3, #0]
mov r2, r1, asr #8
strb r2, [r3, #1]