2017-10-18 136 views
0

我想86教我,我已經在整個運行需要返回立即,負數:我可以在x86中編碼64位負立即數嗎?

.text 
.align 4,0x90 
.globl _scheme_entry 
_scheme_entry: 
movl $-42, %eax 
ret 

當我打印這個功能(printf("%" PRIdPTR "\n", scheme_entry())的返回值,我得到一個廢話號:

$ ./neg             
4294967254 

我猜這是因爲它是一個32位負,00000000FFFFFFFF,而不是64位負,FFFFFFFFFFFFFFFF

我如何可以存儲恆定的64位值。直接在彙編函數中上?我必須將它編碼爲兩個單獨的指令嗎?

+0

你打印錯了嗎? 'scheme_entry'似乎返回一個32位整數(如果不是,那麼你爲什麼把它放在'eax'中?) – harold

+0

gcc通常將函數入口點對齊到16個字節。也沒有理由強制填充爲單字節NOP(因爲它永遠不會運行)。使用'.p2align 4'對齊到'1 << 4'。 (對於這樣一個小函數,一個8字節的邊界將覆蓋整個函數,所以你可能會使用'.p2align 3'。)現代CPU對代碼對齊不如舊CPU那麼敏感,但是當它仍然是一個好主意的時候NOP填充將不會執行。 –

+0

@PeterCordes相當多的是在我頭上 - 我跟着[編譯器編寫教程](http://scheme2006.cs.uchicago.edu/11-ghuloum.pdf),這是故意讓我們使用'gcc'的輸出來處理微小的C輸入,以決定從編譯器發出什麼。上面的樣板基本上是逐字拷貝的,但我還沒有學到它的功能! :x – ELLIOTTCABLE

回答

3

用於32位指令的32位立即數(如movl)原樣使用,而writing EAX zeros the upper 32 bits of RAX。你沒有得到廢話,你得到2^32 - 42,這正是你應該期望的,因爲x86使用2的補碼有符號整數。

64位操作數大小的指令的32位立即數符號擴展爲64位。使用mov $-42, %rax返回負64位值,而不是稍微低於2^32的正64位值。 (使用%rax作爲目的地意味着64位操作數大小,即movq。)

使用調試器查看寄存器中的值。

+0

這是極好的信息!是的,我知道兩個補碼;但'%rax'(和'mov' vs'movl',顯然?)是我在這裏失蹤的作品。我會跑這個!謝謝! – ELLIOTTCABLE

+2

@ELLIOTTCABLE相反,它的movl vs movq。如果操作數清楚,後綴可以省略。 – fuz

相關問題