2017-07-02 2 views
0

Ich schreibe eine Subroutine, die den Dezimalwert von allem, was in rdi übergeben wird, ausgeben soll. Es funktioniert hervorragend für jede Nummer, die mit 32 Bit dargestellt werden kann. Sobald 64-Bit-Werte betroffen sind, bricht etwas zusammen.Wie drucke ich eine 64-Bit-Nummer in NASM?

Wenn ich 4294967295 oder 0000000000000000000000000000000011111111111111111111111111111111b als Argument übergeben, wird wie erwartet gedruckt. Aber wenn ich mache

mov rdi, 4294967295 
inc rdi 
call Print_Unsinged 

bekomme ich das falsche Ergebnis (X96 um genau zu sein).

Ich überprüfe die Größe des Arguments auf diese Weise:

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 

Was am Ende passiert ist, dass ein Wert, den Bits über ebx gesetzt haben sollte und zu isQword springen, anstatt zu isDword springt. Der erste gedruckte Buchstabe endet also als Abfall, während der Rest der Zahl gut gedruckt wird. Sehen Sie sich das erste Code-Snippet an: Ich würde erwarten, dass der Argumentwert 00000000000000000000000000000000010000000000000000000000000000000000b ist, und dann würde das einen Sprung zu isQword auslösen, weil rbx ein Bit gesetzt hätte, nachdem ebx gelöscht wurde. Aber nein, dieser Wert filtert bis runter zu isByte und gibt "X96" aus.

Ich kann das nicht herausfinden, kann jemand helfen?

+3

32-Bit-Operationen Null die oberen 32 Bits automatisch, so dass Ihr Test fehlschlägt. 'shr rbx, 32; jnz isQword' ist eine Alternative. – Jester

+1

Wo ist der Rest Ihres Codes? –

+0

Dies hat das Potenzial, eine gute Frage zu sein. Es ist erfrischend für das Linux-Tag. Sie müssen den Code anzeigen, den Sie zum Drucken des 64-Bit-Registers verwenden. nicht das Snippet, mit dem die Größe überprüft wird. Es scheint auch eine Trennung in dem von Ihnen bereitgestellten Code zu geben. Sie zeigen den Wert in 'rdi', aber dann beginnen Sie mit einem Wert in' rax'. 'rbx' sollte wahrscheinlich beibehalten werden, da es für die Global Offset Table (GOT) in einer Menge Code verwendet wird. – jww

Antwort

2

Dies wurde gelöst, danke!

der Grund, dass mein Code einen 64-Bit-Wert nicht erkennen konnte (wie jemand darauf hingewiesen hat), dass eine 32-Bit-Operation an einem Register die oberen 32 Bits dieses Registers löscht.