-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmmx_ternary.asm
62 lines (46 loc) · 1.6 KB
/
mmx_ternary.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
53
54
55
56
57
58
59
60
61
62
section .text
global _ternary
_ternary:
; eax - адрес первого массива слов (контрольная последовательность), снятый со стека
; edx - второго (первые варианты)
; ecx - третьего (вторые варианты)
mov eax, [esp + 4]
mov edx, [esp + 8]
mov ecx, [esp + 12]
; mm1 - контрольная последовательность (cseq)
; mm2 - первая последовательность слов (f)
; mm3 - вторая последовательность слов (s)
; res[i] = (cseq[i] != 0x00) ? f[i] : s[i]
movq mm1, [eax]
movq mm2, [edx]
movq mm3, [ecx]
pcmpeqw mm1, [ZERO]
; mm1[i] = 0xFF, если cseq[i] = 0x00
; mm1[i] = 0x00, иначе
pand mm3, mm1
; 1) если cseq[i] = 0x00, то mm1[i] = 0xFF
; тогда mm3[i] = mm3[i] & mm1[i] = mm3[i] & 0xFF = mm3[i]
; (то есть mm3[i] остаётся неизменной, если cseq[i] = 0x00).
; 2) если cseq != 0x00, то mm1[i] = 0x00, тогда
; mm3[i] = mm3[i] & mm1[i] = mm3[i] & 0x00 = 0
; (то есть mm3[i] обнуляется, если cseq[i] != 0x00)
; mm3 хранит изменённую нужным образом вторую последовательность
pandn mm1, mm2
; 1) если cseq[i] = 0x00, то mm1[i] = 0xFF, тогда ~mm1[i] = 0x00
; тогда mm1[i] = mm2[i] & 0x00 = 0
; 2) если cseq[i] != 0x00, то mm1[i] = 0x00, тогда ~mm1[i] = 0xFF
; тогда mm1[i] = mm2[i] & 0xFF = mm2[i]
; то есть mm1 хранит изменённую необходимым образом первую последовательность слов
por mm1, mm3
; объединяем результаты. mm1 = result
; записываем в память объединённые результаты
movq [answer], mm1
; возвращаем адрес памяти, куда записан результат
mov eax, answer
; пометить все mm-регистры как свободные (для соблюдения конвенции вызова)
emms
ret
section .bss
answer : resw 4
section .rdata
ZERO : dw 0, 0, 0, 0