程式會執行 L17。
改成以下才會是正確的執行結果:
11 if (d <= (int)TOTAL_E - 2)
書上的解釋就不用在說明了, 我不是要把書上有的東西重提一次。組合語言下沒有秘密, 我們來看看反組譯的差別。
right case:
8048435: 89 e5 mov %esp,%ebp
8048437: 83 e4 f0 and $0xfffffff0,%esp
804843a: 83 ec 20 sub $0x20,%esp
804843d: c7 44 24 1c ff ff ff movl $0xffffffff,0x1c(%esp) 8048444: ff
8048445: 83 7c 24 1c 05 cmpl $0x5,0x1c(%esp)
804844a: 7f 0e jg 804845a
804844c: c7 04 24 30 85 04 08 movl $0x8048530,(%esp)
8048453: e8 18 ff ff ff call 8048370
8048458: eb 0c jmp 8048466
804845a: c7 04 24 32 85 04 08 movl $0x8048532,(%esp)
8048461: e8 0a ff ff ff call 8048370
8048466: b8 00 00 00 00 mov $0x0,%eax
804846b: c9 leave
804846c: c3 ret
804846d: 8d 76 00 lea 0x0(%esi),%esi
wrong case:
8048434: 55 push %ebp
8048435: 89 e5 mov %esp,%ebp
8048437: 83 e4 f0 and $0xfffffff0,%esp
804843a: 83 ec 20 sub $0x20,%esp
804843d: c7 44 24 1c ff ff ff movl $0xffffffff,0x1c(%esp) 8048444: ff
8048445: 8b 44 24 1c mov 0x1c(%esp),%eax
8048449: 83 f8 05 cmp $0x5,%eax
804844c: 77 0e ja 804845c
804844e: c7 04 24 30 85 04 08 movl $0x8048530,(%esp)
8048455: e8 16 ff ff ff call 8048370
804845a: eb 0c jmp 8048468
804845c: c7 04 24 32 85 04 08 movl $0x8048532,(%esp)
8048463: e8 08 ff ff ff call 8048370
8048468: b8 00 00 00 00 mov $0x0,%eax
804846d: c9 leave
804846e: c3 ret
804846f: 90 nop
signed greater than JG BGT BGT sign=overflow and not zero
unsigned above (higher) JA BHI BHI * not borrow and not zero
一個用 unsigned 另外一個用 signed 來 compare, 於是 0xffffffff 被當成 4,294,967,295 和 -1, 這就是陷阱。
來看看 arm cortex-m3 的版本, 很難看是吧!我也覺得很難看, 我不是要說明 arm 組合語言, 所以只要看紅色部份就好, 簡單多了吧!
4294967295 是 0xffffffff 也是 -1
right
dc6: f04f 33ff mov.w r3, #4294967295
dca: 62fb str r3, [r7, #44] ; 0x2c
dcc: 6afb ldr r3, [r7, #44] ; 0x2c
dce: 2b05 cmp r3, #5
dd0: dc0a bgt.n de8
dd2: f44f 4088 mov.w r0, #17408 ; 0x4400
dd6: f2c4 0000 movt r0, #16384 ; 0x4000
dda: f640 61d8 movw r1, #3800 ; 0xed8
dde: f2c0 0100 movt r1, #0
de2: f7ff fce3 bl 7ac
de6: e009 b.n dfc
de8: f44f 4088 mov.w r0, #17408 ; 0x4400
dec: f2c4 0000 movt r0, #16384 ; 0x4000
df0: f640 61dc movw r1, #3804 ; 0xedc
df4: f2c0 0100 movt r1, #0
df8: f7ff fcd8 bl 7ac
wrong
dc6: f04f 33ff mov.w r3, #4294967295
dca: 62fb str r3, [r7, #44] ; 0x2c
dcc: 6afb ldr r3, [r7, #44] ; 0x2c
dce: 2b05 cmp r3, #5
dd0: d80a bhi.n de8
dd2: f44f 4088 mov.w r0, #17408 ; 0x4400
dd6: f2c4 0000 movt r0, #16384 ; 0x4000
dda: f640 61d8 movw r1, #3800 ; 0xed8
dde: f2c0 0100 movt r1, #0
de2: f7ff fce3 bl 7ac
de6: e009 b.n dfc
de8: f44f 4088 mov.w r0, #17408 ; 0x4400
dec: f2c4 0000 movt r0, #16384 ; 0x4000
df0: f640 61dc movw r1, #3804 ; 0xedc
df4: f2c0 0100 movt r1, #0
df8: f7ff fcd8 bl 7ac
bhi.n unsigned
bgt.n signed
一樣有針對有號數無號數的比較指令。
一個用 unsigned 另外一個用 signed 來 compare, 於是 0xffffffff 被當成 4,294,967,295 和 -1, 這就是陷阱。
來看看 arm cortex-m3 的版本, 很難看是吧!我也覺得很難看, 我不是要說明 arm 組合語言, 所以只要看紅色部份就好, 簡單多了吧!
4294967295 是 0xffffffff 也是 -1
right
dc6: f04f 33ff mov.w r3, #4294967295
dca: 62fb str r3, [r7, #44] ; 0x2c
dcc: 6afb ldr r3, [r7, #44] ; 0x2c
dce: 2b05 cmp r3, #5
dd0: dc0a bgt.n de8
dd2: f44f 4088 mov.w r0, #17408 ; 0x4400
dd6: f2c4 0000 movt r0, #16384 ; 0x4000
dda: f640 61d8 movw r1, #3800 ; 0xed8
dde: f2c0 0100 movt r1, #0
de2: f7ff fce3 bl 7ac
de6: e009 b.n dfc
de8: f44f 4088 mov.w r0, #17408 ; 0x4400
dec: f2c4 0000 movt r0, #16384 ; 0x4000
df0: f640 61dc movw r1, #3804 ; 0xedc
df4: f2c0 0100 movt r1, #0
df8: f7ff fcd8 bl 7ac
wrong
dc6: f04f 33ff mov.w r3, #4294967295
dca: 62fb str r3, [r7, #44] ; 0x2c
dcc: 6afb ldr r3, [r7, #44] ; 0x2c
dce: 2b05 cmp r3, #5
dd0: d80a bhi.n de8
dd2: f44f 4088 mov.w r0, #17408 ; 0x4400
dd6: f2c4 0000 movt r0, #16384 ; 0x4000
dda: f640 61d8 movw r1, #3800 ; 0xed8
dde: f2c0 0100 movt r1, #0
de2: f7ff fce3 bl 7ac
de6: e009 b.n dfc
de8: f44f 4088 mov.w r0, #17408 ; 0x4400
dec: f2c4 0000 movt r0, #16384 ; 0x4000
df0: f640 61dc movw r1, #3804 ; 0xedc
df4: f2c0 0100 movt r1, #0
df8: f7ff fcd8 bl 7ac
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。