2017-07-02 114 views
0

我正在寫一個子程序,它應該打印rdi中傳遞給它的任何數據的十進制值。它適用於每個可以用32位表示的數字。一旦涉及64位值,事情就會崩潰。如何在NASM中打印64位數字?

如果我將4294967295或000000000000000000000000000011111111111111111111111111111111b作爲參數傳遞,按預期打印。但如果我做

mov rdi, 4294967295 
inc rdi 
call Print_Unsinged 

我得到了錯誤的結果(X96是確切的)。

我檢查參數的大小是這樣的:

mov rbx, rax ; rax has the orginal arg at this point 
xor ebx, eax 
cmp rbx, 0 
jne isQword 

mov ebx, eax 
xor bx, ax 
cmp ebx, 0 
jne isDword 

cmp ah, 0 
jne isWord 

jmp isByte 

什麼最終情況是,應該有超越EBX集位,應該跳到isQword值跳躍而不是isDword。所以打印的第一個字符最終是垃圾,而其餘的數字打印罰款。看看第一個代碼片段:我期望參數值爲0000000000000000000000000000000100000000000000000000000000000000b,然後這將觸發跳轉到isQword,因爲在ebx被清除後,rbx會設置一個位。但是,不,這個值一直過濾到isByte並打印「X96」。

我無法弄清楚,任何人都可以幫忙嗎?

+3

32位操作自動清零前32位,所以你的測試失敗。 'shr rbx,32; jnz isQword'是另一種選擇。 – Jester

+1

你的代碼的其餘部分在哪裏? –

+0

這有可能是一個很好的問題。它爲Linux標籤刷新。您需要顯示您用來打印64位寄存器的代碼;而不是用於檢查大小的代碼段。您提供的代碼似乎也存在脫節。你在'rdi'中顯示值,然後你開始在'rax'中使用一個值。 'rbx'應該被保留下來,因爲它在很多代碼中用於全局偏移表(GOT)。 – jww

回答

2

這個已經解決了,謝謝!

我的代碼無法檢測到64位值(如某人指出的)的原因是對寄存器執行32位操作會清除該寄存器的高32位。

; rax has the orginal rdi argument at this point in the code 
mov rbx, rax 
xor ebx, eax ; this clears the upper 32 bits of rbx 
cmp rbx, 0 ; these are equal 
jne isQword ; so we don't get to isQword when we should