]> 4ch.mooo.com Git - 16.git/blob - 16/scrasm/80X86.ASC
more
[16.git] / 16 / scrasm / 80X86.ASC
1 _80x86 OPTIMIZATION_\r
2 by Michael Abrash\r
3 \r
4 \r
5 [LISTING ONE]\r
6 \r
7 ; Copies one string to another string, converting all characters to\r
8 ; uppercase in the process, using a loop containing LODSB and STOSB.\r
9 ; Adapted from Zen of Assembly Language, by Michael Abrash; not a\r
10 ; standalone program, but designed to be used with the Zen timer from\r
11 ; that book via the Zen timer's PZTIME.BAT batch file: ZTimerOn starts\r
12 ; the clock, ZTimerOff stops it, and the test-bed program linked in by\r
13 ; PZTIME.BAT starts the program, reports the results, and ends.\r
14 \r
15         jmp     Skip            ;skip over data in CS and subroutine\r
16 \r
17 SourceString    label   word            ;sample string to copy\r
18         db      'This space intentionally left not blank',0\r
19 DestString      db      100 dup (?)     ;destination for copy\r
20 \r
21 ; Copies one zero-terminated string to another string,\r
22 ; converting all characters to uppercase.\r
23 ; Input: DS:SI = start of source string; DS:DI = start of destination buffer\r
24 ; Output: none\r
25 ; Registers altered: AX, BX, SI, DI, ES\r
26 ; Direction flag cleared\r
27 \r
28 CopyStringUpper:\r
29         mov     ax,ds\r
30         mov     es,ax   ;for STOS\r
31         mov     bl,'a'  ;set up for fast register-register\r
32         mov     bh,'z'  ; comparisons\r
33         cld\r
34 StringUpperLoop:\r
35         lodsb           ;get next character and point to following character\r
36         cmp     al,bl   ;below 'a'?\r
37         jb      IsUpper ;yes, not lowercase\r
38         cmp     al,bh   ;above 'z'?\r
39         ja      IsUpper ;yes, not lowercase\r
40         and     al,not 20h ;is lowercase-make uppercase\r
41 IsUpper:\r
42         stosb           ;put character into new string and point to \r
43                         ; following location\r
44         and     al,al   ;is this the zero that marks end of the string?\r
45         jnz     StringUpperLoop ;no, do the next character\r
46         ret\r
47 \r
48 ; Calls CopyStringUpper to copy & convert SourceString->DestString.\r
49 Skip:\r
50         call    ZTimerOn                ;start timing\r
51         mov     si,offset SourceString  ;point SI to the string to copy from\r
52         mov     di,offset DestString    ;point DI to the string to copy to\r
53         call    CopyStringUpper         ;copy & convert to uppercase\r
54         call    ZTimerOff               ;stop timing\r
55 \r
56 \r
57 [LISTING TWO]\r
58 \r
59 ; Copies one string to another string, converting all characters to\r
60 ; uppercase in the process, using no string instructions.\r
61 ; Not a standalone program, but designed to be used with the Zen\r
62 ; timer, as described in Listing 1.\r
63 \r
64         jmp     Skip            ;skip over data in CS and subroutine\r
65 \r
66 SourceString    label   word            ;sample string to copy\r
67         db      'This space intentionally left not blank',0\r
68 DestString      db      100 dup (?)     ;destination for copy\r
69 \r
70 ; Copies one zero-terminated string to another string,\r
71 ; converting all characters to uppercase. \r
72 ; Input: DS:SI = start of source string; DS:DI = start of destination string\r
73 ; Output: none\r
74 ; Registers altered: AL, BX, SI, DI\r
75 \r
76 CopyStringUpper:\r
77         mov     bl,'a'  ;set up for fast register-register\r
78         mov     bh,'z'  ; comparisons\r
79 StringUpperLoop:\r
80         mov     al,[si] ;get the next character and\r
81         inc     si      ; point to the following character\r
82         cmp     al,bl   ;below 'a'?\r
83         jb      IsUpper ;yes, not lowercase\r
84         cmp     al,bh   ;above 'z'?\r
85         ja      IsUpper ;yes, not lowercase\r
86         and     al,not 20h ;is lowercase-make uppercase\r
87 IsUpper:\r
88         mov     [di],al ;put the character into the new string and\r
89         inc     di      ; point to the following location\r
90         and     al,al   ;is this the zero that marks the end of the string?\r
91         jnz     StringUpperLoop ;no, do the next character\r
92         ret\r
93 \r
94 ; Calls CopyStringUpper to copy & convert SourceString->DestString.\r
95 Skip:\r
96         call    ZTimerOn\r
97         mov     si,offset SourceString  ;point SI to the string to copy from\r
98         mov     di,offset DestString    ;point DI to the string to copy to\r
99         call    CopyStringUpper         ;copy & convert to uppercase\r
100         call    ZTimerOff\r
101 \r
102 \r
103 [LISTING THREE]\r
104 \r
105 ; Clears a buffer using MOV/ADD in a loop.\r
106 ; Not a standalone program, but designed to be used with the Zen\r
107 ; timer, as described in Listing 1.\r
108 \r
109         mov     dx,2            ;repeat the test code twice, to make\r
110                                 ; sure it's in the cache (if there is one)\r
111         mov     bx,dx           ;distance from the start of one word\r
112                                 ; to the start of the next\r
113         sub     ax,ax           ;set buffer to zeroes\r
114 TestTwiceLoop:\r
115         mov     cx,1024         ;clear 1024 words starting at address\r
116         mov     di,8000h        ; DS:8000h (this is just unused memory\r
117                                 ; past the end of the program)\r
118         call    ZTimerOn        ;start timing (resets timer to 0)\r
119 StoreLoop:\r
120         mov     [di],ax         ;clear the current word\r
121         add     di,bx           ;point to the next word\r
122         dec     cx              ;count off words to clear until none\r
123         jnz     StoreLoop       ; remain\r
124         call    ZTimerOff       ;stop timing\r
125         dec     dx              ;count off passes through test code\r
126         jz      StoreDone       ;that was the second pass; we're done\r
127         jmp     TestTwiceLoop   ;that was first pass; do second pass with all \r
128                                 ; instructions and data in the cache\r
129 StoreDone:\r
130 \r
131 \r
132 [LISTING FOUR]\r
133 \r
134 ; Clears a buffer using MOV/ADD in an unrolled loop.\r
135 ; Not a standalone program, but designed to be used with the Zen\r
136 ; timer, as described in Listing 1.\r
137 \r
138         mov     dx,2            ;repeat the test code twice, to make\r
139                                 ; sure it's in the cache (if there is one)\r
140         mov     bx,dx           ;distance from the start of one word\r
141                                 ; to the start of the next\r
142         sub     ax,ax           ;set buffer to zeroes\r
143 TestTwiceLoop:\r
144         mov     si,1024         ;clear 1024 words starting at address\r
145         mov     di,8000h        ; DS:8000h (this is just unused memory\r
146                                 ; past the end of the program)\r
147         call    ZTimerOn        ;start timing (resets timer to 0)\r
148         mov     cl,4            ;divide the count of words to clear by\r
149         shr     si,cl           ; 16, because we'll clear 16 words\r
150                                 ; each time through the loop\r
151 StoreLoop:\r
152         REPT    16              ;clear 16 words in a row without looping\r
153         mov     [di],ax         ;clear the current word\r
154         add     di,bx           ;point to the next word\r
155         ENDM\r
156         dec     si              ;count off blocks of 16 words to clear\r
157         jnz     StoreLoop       ; until none remain\r
158         call    ZTimerOff       ;stop timing\r
159         dec     dx              ;count off passes through test code\r
160         jz      StoreDone       ;that was the second pass; we're done\r
161         jmp     TestTwiceLoop   ;that was the first pass; do the second pass \r
162                                 ; with all instructions and data in the cache\r
163 StoreDone:\r
164 \r