我想要打印一個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指令做...
我想要打印一個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指令做...
有沒有x86指令「打印」的值。顯示輸出需要操作系統特定的接口。在「經典」x86編程中,您將進行BIOS調用以生成輸出到屏幕。在現代保護模式操作系統中,這將不再起作用。相反,您需要調用OS API函數來顯示輸出,例如,例如添加到與您的流程關聯的控制檯窗口。
調用該OS API的最簡單和最通用的方法是將彙編程序與C標準庫鏈接,以便您可以調用其printf
(及類似函數)函數。這隻需要一個CALL
指令,它將控制權轉移給printf
函數,執行它,並將控制權返回到代碼中的以下指令。
但是,還有一個額外的複雜因素:您必須遵循相應的調用約定您的平臺和標準庫函數。你的問題沒有提供你是否使用Windows,Linux或其他的線索。幸運的是,有關x86調用約定的詳細信息可在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
僞指令,可以自動處理爲你調用函數。查看您選擇的彙編程序是否具有類似功能可能值得一試。
打印出來 - 如何?十進制,十六進制,二進制?你能想出如何在你選擇的符號系統中打印單個字節值嗎? – usr2564301
如果是十進制數,那麼可以在這裏檢查一個例程:http://tw.wikipedia.org/wiki/Http://www.stackoverflow.com/a/41086442/4271923(順便說一句,不要把整個例程放到宏中,它會在機器代碼中爲每個用法重複=>大二進制=>慢,而是使用'call'和子程序。) – Ped7g
我發現一個非常簡單的方法: push ebx;低32位 push eax;高32位 推送偏移格式 call printf add esp,12;清除堆棧 格式爲 格式DB「%lld」,0 – Crisan