-
Notifications
You must be signed in to change notification settings - Fork 20
/
0x22.asm
52 lines (49 loc) · 1.57 KB
/
0x22.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
;
; $Id: 0x22.asm,v 1.1.1.1 2016/03/27 08:40:13 raptor Exp $
;
; 0x22 explanation - from xchg rax,rax by [email protected]
; Copyright (c) 2016 Marco Ivaldi <[email protected]>
;
; This snippet illustrates a clever (if convoluted) way to perform an
; Euclidean (integer) division by 3 of the value stored in rax. It does
; so by exploiting the overflow of the unsigned multiplication performed
; on rax and the constant value 0xaaaaaaaaaaaaaaab (which in binary is
; 0b1010101010101010101010101010101010101010101010101010101010101011).
;
; This analysis was facilitated by the assembly REPL rappel
; by [email protected]:
;
; https://github.com/yrp604/rappel/
;
; Example:
; $ ./rappel
; > mov rax,5
; rax: 0x0000000000000005 rdx: 0x0000000000000000
; > mov rdx,0xaaaaaaaaaaaaaaab
; rax: 0x0000000000000005 rdx: 0xaaaaaaaaaaaaaaab
; > mul rdx
; rax: 0x5555555555555557 rdx: 0x0000000000000003
; > shr rdx,1
; rax: 0x5555555555555557 rdx: 0x0000000000000001
; > mov rax,rdx
; rax: 0x0000000000000001 rdx: 0x0000000000000001 <- 5 / 3 = 1
; [...]
; > mov rax,766
; rax: 0x00000000000002fe rdx: 0x0000000000000000
; > mov rdx,0xaaaaaaaaaaaaaaab
; rax: 0x00000000000002fe rdx: 0xaaaaaaaaaaaaaaab
; > mul rdx
; rax: 0xaaaaaaaaaaaaabaa rdx: 0x00000000000001fe
; > shr rdx,1
; rax: 0xaaaaaaaaaaaaabaa rdx: 0x00000000000000ff
; > mov rax,rdx
; rax: 0x00000000000000ff rdx: 0x00000000000000ff <- 766 / 3 = 255
;
BITS 64
SECTION .text
global main
main:
mov rdx,0xaaaaaaaaaaaaaaab ; rdx = 0xaaaaaaaaaaaaaaab
mul rdx ; rdx:rax = rax * rdx
shr rdx,1 ; rdx = (int)rdx / 2
mov rax,rdx ; rax = rdx