2016-12-13 56 views
0

我想要打印一個qword(十進制)的宏。打印存儲在eax中的qword:ebx x86

show_qd macro nr 
    lea edx,[nr] 
    mov eax,[edx] ;upper 32 bits 
    mov ebx,[edx+4] ;lower 32 bits 

    ;print code here; 

endm 

可悲的是,我無法弄清楚如何與x86指令做...

+2

打印出來 - 如何?十進制,十六進制,二進制?你能想出如何在你選擇的符號系統中打印單個字節值嗎? – usr2564301

+1

如果是十進制數,那麼可以在這裏檢查一個例程:http://tw.wikipedia.org/wiki/Http://www.stackoverflow.com/a/41086442/4271923(順便說一句,不要把整個例程放到宏中,它會在機器代碼中爲每個用法重複=>大二進制=>慢,而是使用'call'和子程序。) – Ped7g

+1

我發現一個非常簡單的方法: push ebx;低32位 push eax;高32位 推送偏移格式 call printf add esp,12;清除堆棧 格式爲 格式DB「%lld」,0 – Crisan

回答

0

有沒有x86指令「打印」的值。顯示輸出需要操作系統特定的接口。在「經典」x86編程中,您將進行BIOS調用以生成輸出到屏幕。在現代保護模式操作系統中,這將不再起作用。相反,您需要調用OS API函數來顯示輸出,例如,例如添加到與您的流程關聯的控制檯窗口。

調用該OS API的最簡單和最通用的方法是將彙編程序與C標準庫鏈接,以便您可以調用其printf(及類似函數)函數。這隻需要一個CALL指令,它將控制權轉移給printf函數,執行它,並將控制權返回到代碼中的以下指令。

但是,還有一個額外的複雜因素:您必須遵循相應的調用約定您的平臺和標準庫函數。你的問題沒有提供你是否使用Windows,Linux或其他的線索。幸運的是,有關x86調用約定的詳細信息可在標記wiki中找到,可訪問here。通常,32位調用約定將從右到左傳遞堆棧中的參數。而C標準庫函數實際上總是調用者清理(即使在Windows中,其中被調用者清除約定是常見的),因此您負責在進行調用後清理堆棧。

因此,只是作爲一個演示,這裏是你會怎麼稱呼printf打印存儲在EAX寄存器中的32位整數:

push eax     ; push 32-bit integer value from EAX onto stack 
push OFFSET strFormat  ; push pointer to format string onto stack 
call printf 
add esp, 8    ; clean up stack 

strFormat必須存儲在您的可執行文件的DATA部分的字符串。格式字符串與C相同,因爲它的功能完全相同。在這種情況下,它會將指針指向包含"%d"的字符串。

除了您的格式字符串是"%lld"(在C中使用long long類型,在x86-32上是64位)之外,打印64位值的內容大致相同。您需要遵循調用約定的規則,將64位整數參數傳遞給函數。這很可能只是將兩個32位的數據壓入堆棧。假設64位值規範地存儲在EDX:EAX,代碼如下:

lea edx, DWORD PTR [value] 
mov eax, DWORD PTR [edx] 
mov edx, DWORD PTR [edx+4] 

push edx 
push eax 
push OFFSET strFormat64 
call printf 

add esp, 12 

push edx     ; push upper 32 bits of 64-bit integer value onto stack 
push eax     ; push lower 32 bits of 64-bit integer value onto stack 
push OFFSET strFormat64  ; push pointer to format string onto stack 
call printf 
add esp, 12    ; clean up stack 

如果該值是在內存中,然後就可以像你在問題中顯示使用代碼

請注意,如果您將此實現爲宏,它將會觸發寄存器。確保這是明確記錄的,還是保存並恢復宏內的寄存器 - 否則,當在代碼中使用它時,最終會出現難以調試的問題!而且,根據您的調用約定,您可能需要確保堆棧已正確對齊,這在宏中很難做到乾淨利落。 MASM有一個INVOKE僞指令,可以自動處理爲你調用函數。查看您選擇的彙編程序是否具有類似功能可能值得一試。