在86

2016-02-19 71 views
0

推進結構類型的內容壓入堆棧可以說,我已經聲明瞭一個結構,像這樣:在86

struct VEC 
    x dd ? 
    y dd ? 
ends 

然後我聲明瞭一些數據結構:

section '.data' data readable writeable 
vec1   VEC  5,4 
vec2   VEC  3,2 

現在,我想將內存位置vec1和vec2的內容推送到堆棧。我這樣做:

push sizeof.VEC [vec1]   
push sizeof.VEC [vec2] 

這不會編譯。返回的錯誤是:

error: operand size not specified.

我想知道是否有什麼辦法可以把這種結構類型的內容壓入堆棧。或者這在x86中是非法的呢?

我使用平板彙編版本1.71.49

一般來說在Windows 10編譯此,我的問題是關於如何讓彙編器進行編碼推[存儲]用正確的操作數大小

+1

'sizeof.VEC'是一個數字表達式。 '8 [vec1]'是否意味着FASM中的[vec1 + 8]?如果是這樣,那就是你會得到的(如果你在其他操作數大小被暗示的上下文中使用它,或者使用'qword'或'qword ptr'。無論如何,這只是一個如何獲得你的彙編程序用正確的操作數大小對一個'push [mem]'進行編碼(16位和64位的壓入可以在64位模式下進行編碼,但不是32位的壓入)'REX.W = 0推動某些錯誤爲非法指令,相反英特爾的insn ref手冊聲稱操作數大小可能會被'66H'或'REX.W'覆蓋 –

+0

一般來說,就像你指出的那樣,我的問題是關於如何讓彙編器編碼push [mem]正確的操作數大小 – user1720897

+0

這是對*的迴應或者這在x86中是非法的?*這很簡單:如果你的結構是16或64b,那麼是的,否則不行! –

回答

2

這只是一個如何讓你的彙編程序用正確的操作數大小對push [mem]進行編碼的問題。 16位和64位push es可編碼爲64位模式,但不是32位push es。 REX.W=0 push something故障爲非法指令,違背了英特爾的insn的參考手冊,聲稱數大小可與66H或REX.W覆蓋:

操作數的大小。當前代碼段描述符中的D標誌決定了默認操作數大小;它可能被指令前綴(66H或REX.W)覆蓋,可能被 覆蓋。 操作數大小(16,32或64位)決定堆棧指針遞減的數量(2,4, 或8)。

請注意,這是記錄32位和64位模式。 32位推送當然可以在32位模式下使用。 (維基鏈接到手動)


由於有大量的結構尺寸是不被按壓用一條指令,那是不可能的,有一個爲選擇一個字,雙字或四字操作數大小的任何語法基於結構大小。不過,如果你真的想要,你可以使用宏來自己做。

push大型結構不是普通的調用約定是如何工作的,所以這是另一個沒有語法糖的原因。通常情況下,太大以至於無法放入寄存器的對象通過引用傳遞。較小的對象可以按值傳遞。所以你不能只參數化push的操作數大小來製作靈活的代碼;你需要使用一個宏來發送一個不同的指令來傳遞值和傳遞引用,這取決於結構體的大小。

因爲你的結構是64位的,你只能推的整體結構與64位模式下單指令:

push qword [vec1] 
push qword [vec2] 

(或者qword ptr,如果FASM使用MASM語法而不是NASM)。