XCHG RAX, RAX: 0x09, what does this code do and how does it work?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
1
down vote

favorite












Given the following short assembly snippet:



shr rax, 3
adc rax, 0


I worked this out a bit:



  • We know SHR sets the CF with the last bit shifted.

  • We know ADC dest, 0 is just adding the CF.

So looking at the bits,



 128 64 32 16 8 4 2 1 
8 7 6 5 4 3 2 1
------------------------------
1 1 1 1 1 CF X X
CF=1 | 0 0 0 1 1 1 1 1 ; shr 3


So if we div 8 and add the CF the most correct function is something like this,



def f(x):
return x//8 + int( (x//4) % 2 )


When would that be useful. Quickly testing it, I can see that I am right.



rax = 0 -> 0
rax = 1 -> 0
rax = 2 -> 0
rax = 3 -> 0

rax = 4 -> 1
rax = 7 -> 1
rax = 8 -> 1
rax = 11 -> 1

rax = 12 -> 2
rax = 13 -> 2
rax = 14 -> 2
rax = 15 -> 2
rax = 16 -> 2
rax = 17 -> 2
rax = 18 -> 2
rax = 19 -> 2

...

rax = 20 -> 3
rax = 28 -> 4


Decompilation with Radare is also not useful here,



int64_t entry0 (void) 
rax >>= 3;
__asm ("adc rax, 0");



My questions is, therefore, although I do understand the immediate impact these instructions have on the operand register, what is the higher level meaning of this instruction sequence?




This is riddle 0x09 from the XCHG RAX, RAX book.










share|improve this question























  • xchg rax,rax's puzzles are indeed nice. Is there a question here, though?
    – NirIzr
    2 hours ago










  • @NirIzr yes, quite clearly what's the answer to the riddle? "Riddle" means there is a something it's trying to demonstrate or do, or it has some utility and there is intent behind it. Any two instructions that the CPU can execute will do something (even if only waste time) why were these two instructions chosen?
    – Evan Carroll
    2 hours ago










  • I've figured out what the code does in the machine, but what's the use of that? What useful higher level thing can it be used to do?
    – Evan Carroll
    2 hours ago















up vote
1
down vote

favorite












Given the following short assembly snippet:



shr rax, 3
adc rax, 0


I worked this out a bit:



  • We know SHR sets the CF with the last bit shifted.

  • We know ADC dest, 0 is just adding the CF.

So looking at the bits,



 128 64 32 16 8 4 2 1 
8 7 6 5 4 3 2 1
------------------------------
1 1 1 1 1 CF X X
CF=1 | 0 0 0 1 1 1 1 1 ; shr 3


So if we div 8 and add the CF the most correct function is something like this,



def f(x):
return x//8 + int( (x//4) % 2 )


When would that be useful. Quickly testing it, I can see that I am right.



rax = 0 -> 0
rax = 1 -> 0
rax = 2 -> 0
rax = 3 -> 0

rax = 4 -> 1
rax = 7 -> 1
rax = 8 -> 1
rax = 11 -> 1

rax = 12 -> 2
rax = 13 -> 2
rax = 14 -> 2
rax = 15 -> 2
rax = 16 -> 2
rax = 17 -> 2
rax = 18 -> 2
rax = 19 -> 2

...

rax = 20 -> 3
rax = 28 -> 4


Decompilation with Radare is also not useful here,



int64_t entry0 (void) 
rax >>= 3;
__asm ("adc rax, 0");



My questions is, therefore, although I do understand the immediate impact these instructions have on the operand register, what is the higher level meaning of this instruction sequence?




This is riddle 0x09 from the XCHG RAX, RAX book.










share|improve this question























  • xchg rax,rax's puzzles are indeed nice. Is there a question here, though?
    – NirIzr
    2 hours ago










  • @NirIzr yes, quite clearly what's the answer to the riddle? "Riddle" means there is a something it's trying to demonstrate or do, or it has some utility and there is intent behind it. Any two instructions that the CPU can execute will do something (even if only waste time) why were these two instructions chosen?
    – Evan Carroll
    2 hours ago










  • I've figured out what the code does in the machine, but what's the use of that? What useful higher level thing can it be used to do?
    – Evan Carroll
    2 hours ago













up vote
1
down vote

favorite









up vote
1
down vote

favorite











Given the following short assembly snippet:



shr rax, 3
adc rax, 0


I worked this out a bit:



  • We know SHR sets the CF with the last bit shifted.

  • We know ADC dest, 0 is just adding the CF.

So looking at the bits,



 128 64 32 16 8 4 2 1 
8 7 6 5 4 3 2 1
------------------------------
1 1 1 1 1 CF X X
CF=1 | 0 0 0 1 1 1 1 1 ; shr 3


So if we div 8 and add the CF the most correct function is something like this,



def f(x):
return x//8 + int( (x//4) % 2 )


When would that be useful. Quickly testing it, I can see that I am right.



rax = 0 -> 0
rax = 1 -> 0
rax = 2 -> 0
rax = 3 -> 0

rax = 4 -> 1
rax = 7 -> 1
rax = 8 -> 1
rax = 11 -> 1

rax = 12 -> 2
rax = 13 -> 2
rax = 14 -> 2
rax = 15 -> 2
rax = 16 -> 2
rax = 17 -> 2
rax = 18 -> 2
rax = 19 -> 2

...

rax = 20 -> 3
rax = 28 -> 4


Decompilation with Radare is also not useful here,



int64_t entry0 (void) 
rax >>= 3;
__asm ("adc rax, 0");



My questions is, therefore, although I do understand the immediate impact these instructions have on the operand register, what is the higher level meaning of this instruction sequence?




This is riddle 0x09 from the XCHG RAX, RAX book.










share|improve this question















Given the following short assembly snippet:



shr rax, 3
adc rax, 0


I worked this out a bit:



  • We know SHR sets the CF with the last bit shifted.

  • We know ADC dest, 0 is just adding the CF.

So looking at the bits,



 128 64 32 16 8 4 2 1 
8 7 6 5 4 3 2 1
------------------------------
1 1 1 1 1 CF X X
CF=1 | 0 0 0 1 1 1 1 1 ; shr 3


So if we div 8 and add the CF the most correct function is something like this,



def f(x):
return x//8 + int( (x//4) % 2 )


When would that be useful. Quickly testing it, I can see that I am right.



rax = 0 -> 0
rax = 1 -> 0
rax = 2 -> 0
rax = 3 -> 0

rax = 4 -> 1
rax = 7 -> 1
rax = 8 -> 1
rax = 11 -> 1

rax = 12 -> 2
rax = 13 -> 2
rax = 14 -> 2
rax = 15 -> 2
rax = 16 -> 2
rax = 17 -> 2
rax = 18 -> 2
rax = 19 -> 2

...

rax = 20 -> 3
rax = 28 -> 4


Decompilation with Radare is also not useful here,



int64_t entry0 (void) 
rax >>= 3;
__asm ("adc rax, 0");



My questions is, therefore, although I do understand the immediate impact these instructions have on the operand register, what is the higher level meaning of this instruction sequence?




This is riddle 0x09 from the XCHG RAX, RAX book.







disassembly assembly x86 decompilation x86-64






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 1 hour ago









NirIzr

8,91712268




8,91712268










asked 3 hours ago









Evan Carroll

56612




56612











  • xchg rax,rax's puzzles are indeed nice. Is there a question here, though?
    – NirIzr
    2 hours ago










  • @NirIzr yes, quite clearly what's the answer to the riddle? "Riddle" means there is a something it's trying to demonstrate or do, or it has some utility and there is intent behind it. Any two instructions that the CPU can execute will do something (even if only waste time) why were these two instructions chosen?
    – Evan Carroll
    2 hours ago










  • I've figured out what the code does in the machine, but what's the use of that? What useful higher level thing can it be used to do?
    – Evan Carroll
    2 hours ago

















  • xchg rax,rax's puzzles are indeed nice. Is there a question here, though?
    – NirIzr
    2 hours ago










  • @NirIzr yes, quite clearly what's the answer to the riddle? "Riddle" means there is a something it's trying to demonstrate or do, or it has some utility and there is intent behind it. Any two instructions that the CPU can execute will do something (even if only waste time) why were these two instructions chosen?
    – Evan Carroll
    2 hours ago










  • I've figured out what the code does in the machine, but what's the use of that? What useful higher level thing can it be used to do?
    – Evan Carroll
    2 hours ago
















xchg rax,rax's puzzles are indeed nice. Is there a question here, though?
– NirIzr
2 hours ago




xchg rax,rax's puzzles are indeed nice. Is there a question here, though?
– NirIzr
2 hours ago












@NirIzr yes, quite clearly what's the answer to the riddle? "Riddle" means there is a something it's trying to demonstrate or do, or it has some utility and there is intent behind it. Any two instructions that the CPU can execute will do something (even if only waste time) why were these two instructions chosen?
– Evan Carroll
2 hours ago




@NirIzr yes, quite clearly what's the answer to the riddle? "Riddle" means there is a something it's trying to demonstrate or do, or it has some utility and there is intent behind it. Any two instructions that the CPU can execute will do something (even if only waste time) why were these two instructions chosen?
– Evan Carroll
2 hours ago












I've figured out what the code does in the machine, but what's the use of that? What useful higher level thing can it be used to do?
– Evan Carroll
2 hours ago





I've figured out what the code does in the machine, but what's the use of that? What useful higher level thing can it be used to do?
– Evan Carroll
2 hours ago











1 Answer
1






active

oldest

votes

















up vote
4
down vote



accepted










The shr rax, 3 is an unsigned divide by 8 with truncation towards zero. The inclusion of the adc rax, 0 makes the division round to nearest instead. (Though 0.5 will always be rounded up)



So this operation sets RAX to



  • 1 if RAX is in the range of [4-11] (8*1 ±4)

  • 2 if RAX is in the range of [12-20] (8*2 ±4)

  • 3 if RAX is in the range of [20-27] (8*3 ±4)

You can simplify this further by reducing the shift to 1.



mov rax, 47 ; (remember 47/2 is 23.5)
shr rax, 1 ; rax = 23
adc rax, 0 ; rax = 24


If we do it again,



mov rax, 46 ; (remember 46/2 is 23)
shr rax, 1 ; rax = 23
adc rax, 0 ; rax = 23





share|improve this answer






















  • That's exactly what's happening. I had considered the case of truncate-to-zero, and round-up. but I had not considered the case of nearest.
    – Evan Carroll
    1 hour ago










Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "489"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
noCode: true, onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2freverseengineering.stackexchange.com%2fquestions%2f19735%2fxchg-rax-rax-0x09-what-does-this-code-do-and-how-does-it-work%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
4
down vote



accepted










The shr rax, 3 is an unsigned divide by 8 with truncation towards zero. The inclusion of the adc rax, 0 makes the division round to nearest instead. (Though 0.5 will always be rounded up)



So this operation sets RAX to



  • 1 if RAX is in the range of [4-11] (8*1 ±4)

  • 2 if RAX is in the range of [12-20] (8*2 ±4)

  • 3 if RAX is in the range of [20-27] (8*3 ±4)

You can simplify this further by reducing the shift to 1.



mov rax, 47 ; (remember 47/2 is 23.5)
shr rax, 1 ; rax = 23
adc rax, 0 ; rax = 24


If we do it again,



mov rax, 46 ; (remember 46/2 is 23)
shr rax, 1 ; rax = 23
adc rax, 0 ; rax = 23





share|improve this answer






















  • That's exactly what's happening. I had considered the case of truncate-to-zero, and round-up. but I had not considered the case of nearest.
    – Evan Carroll
    1 hour ago














up vote
4
down vote



accepted










The shr rax, 3 is an unsigned divide by 8 with truncation towards zero. The inclusion of the adc rax, 0 makes the division round to nearest instead. (Though 0.5 will always be rounded up)



So this operation sets RAX to



  • 1 if RAX is in the range of [4-11] (8*1 ±4)

  • 2 if RAX is in the range of [12-20] (8*2 ±4)

  • 3 if RAX is in the range of [20-27] (8*3 ±4)

You can simplify this further by reducing the shift to 1.



mov rax, 47 ; (remember 47/2 is 23.5)
shr rax, 1 ; rax = 23
adc rax, 0 ; rax = 24


If we do it again,



mov rax, 46 ; (remember 46/2 is 23)
shr rax, 1 ; rax = 23
adc rax, 0 ; rax = 23





share|improve this answer






















  • That's exactly what's happening. I had considered the case of truncate-to-zero, and round-up. but I had not considered the case of nearest.
    – Evan Carroll
    1 hour ago












up vote
4
down vote



accepted







up vote
4
down vote



accepted






The shr rax, 3 is an unsigned divide by 8 with truncation towards zero. The inclusion of the adc rax, 0 makes the division round to nearest instead. (Though 0.5 will always be rounded up)



So this operation sets RAX to



  • 1 if RAX is in the range of [4-11] (8*1 ±4)

  • 2 if RAX is in the range of [12-20] (8*2 ±4)

  • 3 if RAX is in the range of [20-27] (8*3 ±4)

You can simplify this further by reducing the shift to 1.



mov rax, 47 ; (remember 47/2 is 23.5)
shr rax, 1 ; rax = 23
adc rax, 0 ; rax = 24


If we do it again,



mov rax, 46 ; (remember 46/2 is 23)
shr rax, 1 ; rax = 23
adc rax, 0 ; rax = 23





share|improve this answer














The shr rax, 3 is an unsigned divide by 8 with truncation towards zero. The inclusion of the adc rax, 0 makes the division round to nearest instead. (Though 0.5 will always be rounded up)



So this operation sets RAX to



  • 1 if RAX is in the range of [4-11] (8*1 ±4)

  • 2 if RAX is in the range of [12-20] (8*2 ±4)

  • 3 if RAX is in the range of [20-27] (8*3 ±4)

You can simplify this further by reducing the shift to 1.



mov rax, 47 ; (remember 47/2 is 23.5)
shr rax, 1 ; rax = 23
adc rax, 0 ; rax = 24


If we do it again,



mov rax, 46 ; (remember 46/2 is 23)
shr rax, 1 ; rax = 23
adc rax, 0 ; rax = 23






share|improve this answer














share|improve this answer



share|improve this answer








edited 29 mins ago









Evan Carroll

56612




56612










answered 1 hour ago









Ian Cook

1,04659




1,04659











  • That's exactly what's happening. I had considered the case of truncate-to-zero, and round-up. but I had not considered the case of nearest.
    – Evan Carroll
    1 hour ago
















  • That's exactly what's happening. I had considered the case of truncate-to-zero, and round-up. but I had not considered the case of nearest.
    – Evan Carroll
    1 hour ago















That's exactly what's happening. I had considered the case of truncate-to-zero, and round-up. but I had not considered the case of nearest.
– Evan Carroll
1 hour ago




That's exactly what's happening. I had considered the case of truncate-to-zero, and round-up. but I had not considered the case of nearest.
– Evan Carroll
1 hour ago

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2freverseengineering.stackexchange.com%2fquestions%2f19735%2fxchg-rax-rax-0x09-what-does-this-code-do-and-how-does-it-work%23new-answer', 'question_page');

);

Post as a guest













































































Comments

Popular posts from this blog

What does second last employer means? [closed]

Installing NextGIS Connect into QGIS 3?

One-line joke