我是 x86_64 編碼的新手,我正在探索各種代碼。
我正在嘗試比較 nasm x86_64 代碼中的字符“A”,但比較不相等。
; Tests the command line. Similar to a C main function:
; int main(int argc, char** argv)
;
; - argc, number of args in rdi
; - argv, pointer to pointer in rsi and argv
global main
extern puts
main:
mov rbp, rdi ; argc in rdi. Save in rbp, caller-saved
mov rbx, rsi ; argv in rsi. Save in rbx, caller-saved
add rbx, 8
dec rbp
mov rdi, [rbx]
cmp rdi, 'A'
je exit1
call puts
mov rax, 0
ret
exit1:
mov rax, 1
ret
如何修改代碼以獲得所需的結果?有一些解決方案,但它使用 8 位暫存器,如此處使用的比較匯編中的字符 nasm,但為了清除我的基礎知識,我想了解為什么像我的代碼這樣的直接比較不起作用。
uj5u.com熱心網友回復:
argv是指向指向空終止字串的指標串列的指標。在頂部,您必須首先取消參考指標mov rbx, [rsi],以便實際檢查*char值串列。運算元的大小
cmp(實際上對于幾乎所有指令)都很重要,參考英特爾的指令參考cmp:當立即數用作運算元時,它被符號擴展為第一個運算元的長度。
您實際上是在比較兩個64 位數量。
有(至少)兩種可能的解決方案:
cmp dil, 'A':您仍然可以一次從記憶體中檢索 8 個位元組,但出于比較目的,您需要指定一個部分暫存器。- Insert
movsx rdi, dilbeforecmp(或與一步中的 fetch 結合movsx rdi, byte [rbx]):正如Jester建議的那樣,您仍然可以執行 64 位比較,但要確保正確設定了高位。
寫作
cmp rdi, 'A'是寫作的替代品cmp rdi, 0x41。執行后,0x41會進行符號擴展,因此您最終會0x00000041與rdi. 現在,如果您之前從 加載8 個 位元組[rbx],則上面的 7 個位元組可能會充滿亂碼,或者說是字串中的字符char。這給你帶來了麻煩。旁注:
puts談到引數傳遞,我不確定您是否可以這樣呼叫。不rdi應該包含以空字符結尾的字串的 地址嗎?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/430132.html
上一篇:Intel64andIA-32ArchitecturesSoftwareDeveloper'sManual對OUT指令的描述是否包含錯誤?
