Hi guys :) in this days im trying to learn assembler in DOS, and i'm think im doing it fine :tongue: what do you think ? but, i am have a question: can this code be optimized ?..


ORG 100h
JMP START

LEDON DB 'The LED was ON',13,10
DB 'Now is OFF...','$'

LEDOFF DB 'The LED was OFF',13,10
DB 'Now is ON...','$'


START:

MOV DX,0278h
IN AL,DX

CMP AL,00000000b
JNZ LED_ON
JMP LED_OFF

LED_ON:
LEA DX,LEDON
MOV AH,9h
INT 21h

;MOV AL,00000000b
XOR AL,AL;Of 'MOV AL,xxx...' and 'XOR AL,AL' which is faster ??

JMP EXIT

LED_OFF:
LEA DX,LEDOFF
MOV AH,9h
INT 21h

;MOV AL,00000001b
XOR AL,1 ;Same with this, which is faster ?

JMP EXIT

EXIT:

MOV DX,0278h
OUT DX,AL


;MOV AH,4Ch
;INT 21h
INT 20h ;I think this is faster... no ? :-D
Posted on 2004-03-08 08:14:29 by JaiKMw
Heh, optimizing something like this is plain silly ;)
Optimizing for size would make more sense in this example
than speed anyway, since this is hardly a timecritical
application, and you'll be bound by the slow Port I/O.

There's even more silly size optimizations to do, I just
regrouped stuff a bit.



ORG 100h

START:

MOV DX,0278h
IN AL,DX

CMP AL,0
JNZ LED_ON

; no reason to do any jumps here, just fallthrough.

LEA DX,LEDOFF
MOV AH,9h
INT 21h

; "OR AL,1" and "MOV AL, 1" are same size, so let's do the more
; logical and correct thing - mov.
MOV AL,1

JMP EXIT

LED_ON:
LEA DX,LEDON
MOV AH,9h
INT 21h

;"XOR AL, AL" and "MOV AL, 0" are same size, but it's sortof
; traditional to do the XOR ;-)
XOR AL,AL

; no reason to JMP here, fallthrough to EXIT
EXIT:

MOV DX,0278h
OUT DX,AL

ret ; works for .COM files when you haven't messed around

; moved data to the end of program to avoid JMP.
LEDON DB 'The LED was ON',13,10
DB 'Now is OFF...','$'

LEDOFF DB 'The LED was OFF',13,10
DB 'Now is ON...','$'
Posted on 2004-03-08 08:40:52 by f0dder
Just note that xor al,1 is not the same as mov al,1
Posted on 2004-03-08 08:47:50 by roticv


Hey ya f0dder yo impressed me, :), that was a pretty optimizing :alright: , i like learn things each day, especially in asm, jojoj :tongue: and from the big ones, thanks for spending some of your time :) , but i am confused about the xor al,1 and mov al,1, why do you said they aren't the same roticv ?? :confused: :)
Posted on 2004-03-08 10:18:44 by JaiKMw

Just note that xor al,1 is not the same as mov al,1


Just to expand on that comment.

xor al, 1 will invert the lower order bit.

So ...
if al == 1, al will then equal 0

if al == 0, al will then equal 1
Posted on 2004-03-08 13:09:28 by gorshing
Yeah gorshing i was confused too, but now i understand why did i do that, when xor al,1 executes AL will always be 0, due to the CMP AL, is for that that f0dder says that is the same, :), never it's gona XOR Al, if AL is 1...
Posted on 2004-03-08 13:24:39 by JaiKMw
How about:


ORG 100h

START:
MOV DX, 0278h
IN AL, DX

XOR AL, 1
OUT DX, AL

MOVZX DX, AL
DEC DX
AND DX, ' N' - 'FF'
ADD (WORD PTR MOD1), DX
SUB (WORD PTR MOD2), DX

LEA DX, MSG
MOV AH, 9h
INT 21h
RET

MSG DB 'The LED was O'
MOD1 DB 'FF',13,10, 'Now is O'
MOD2 DB 'N ...$'


It's a little different in that the value in al isn't 0 or 1, and the message will have an extra space character after the "ON" message.

Mirno
Posted on 2004-03-08 14:36:03 by Mirno
cute, mirno ;)
Posted on 2004-03-08 14:38:29 by f0dder
Hey Mirno that was pretty nice excellent optimizing, i didn't think aboout it! :grin: , yet is a complex program to understand for me :confused: :notsure: , can you explain me a little bit what is for each instruction ?? :tongue: please ;) ?? :alright:
Posted on 2004-03-09 15:44:33 by JaiKMw
First let me say that you should NEVER program like this! If you do, the guy who has to maintain it will hunt you down and kill you. It's confusing, unmaintainable, and only saves you a few bytes. The costs out-weigh the gains!
Having said that, as an exercise it's worth doing this kind of thing to learn.

OK, first of all, I assume that the result of the "in" statement is either 1 or 0. If this isn't the case you'll need to "or al, al / setXX al" to fix this.



ORG 100h

START:
MOV DX, 0278h ; fetch LED on / off value. Expect 1 or 0 only!
IN AL, DX ; AL now contains 1 or 0 denoting LED on or off respectively

XOR AL, 1 ; Invert the LED's state
OUT DX, AL ; and set
; DX will be unmodified by either the IN or XOR statements,
; so we save that instruction by moving this up here.

MOVZX DX, AL ; Copy and zero extend AL into DX
DEC DX ; Decrement DX,
; if the LED was on originally DX will now be 0xFFFF
; if the LED was off originally DX will now be 0x0000

AND DX, ' N' - 'FF'
; Because Intel chips are little endian we need to byte swap the text
; hence <space>, 'N'.
; See note #1 below for more details on this

ADD (WORD PTR MOD1), DX
SUB (WORD PTR MOD2), DX

LEA DX, MSG ; Print the message
MOV AH, 9h
INT 21h
RET ; end of code

MSG DB 'The LED was O'
MOD1 DB 'FF',13,10, 'Now is O'
MOD2 DB 'N ...$'


Note #1:
ON and OFF are different lengths (2 characters vs. 3), but if we lengthen "ON" to "ON " ("ON", <space>), then we only need to modify 'N', <space> to become 'FF' to make only one message necessary. The labels MOD1, and MOD2 are the positions where modification is needed to set the message.

The modification needed is the same as 'N ' - 'FF' added to 'N ' to turn 'N ' into 'FF', and similarly it is the value you need to subtract from 'FF' to get 'N '. Because of the little endian nature of Intel x86 CPUs, the byte order is backwards in a word value, this is why the code is ' N' - 'FF' (<space>, N rather than N, <space>).

The message may be correct already, in which case we doesn't want to modify it. We can do this with comparisons and jumps, but this takes space (although is much more readable).
The "conditional" modification is achieved with like this:

(A - 1) AND some_number = some_number if A = 0;
(A - 1) AND some_number = 0 if A = 1;

A has already been inverted because of the XOR.

So now we ADD and SUB either our modification number, or 0 depending on "NOT _LED_VALUE_".


I hope this helps, I'm afraid I'm not too good at explaining this kind of thing. If you are still having trouble feel free to ask.

Mirno
Posted on 2004-03-10 12:53:10 by Mirno
Wow Mirno, that was a pretty smart optimizing, the thing's aren't clear at all, but i have now the idea , i'm gonna look at a reference of instructions, and some example coding, :) , i think that's gonna help me to understand things at all, its off to say this is the better optimizing ?? no :) , but there's onyl one thing, that i couln't understand,

"OK, first of all, I assume that the result of the "in" statement is either 1 or 0. If this isn't the case you'll need to "or al, al / setXX al" to fix this."

What does it means ? :confused:

Tha value of the IN statement could be another than 1 or 0 ??..

I would appreciate very much you to explain me that ;) :grin: , hope you can, and thanks Mirno :alright:
Posted on 2004-03-10 14:18:49 by JaiKMw
You know, instead of this:
MOVZX DX, AL

DEC DX
AND DX, ' N' - 'FF'
ADD WORD PTR MOD1, DX
SUB WORD PTR MOD2, DX

Why not do this?


DEC AX
AND AX,' N'-'FF'
ADD WORD PTR MOD1,AX
SUB WORD PTR MOD2,AX

This is 4 bytes shorter. We know that AX is 0 on program entry, so we don't have to set AH. And the AND AX is shorter than AND DX.
Posted on 2004-03-10 16:32:27 by Sephiroth3
Sephiroth, the AH half of AX is never set, so it needs to be cleared, although it may be shorter to "xor ah, ah" or similar.
Its an oversight on my part really, I'm used to trying to avoid partial register stalls :) I never assume the value of a register before I set it :)

JaiKMw, the original code you posted will deal with AL like C does a boolean, i.e. Zero is false, any non-zero value is true. This code relies on the value being either 1, or 0, if it isn't then the decrement doesn't yield 0x0000 or 0xFFFF. In order to fix that, you'd need to use one of the "SETxx" instructions, they have the same options as the conditional jumps and set byte registers (AH, AL, BH, BL etc.) to either 1 or 0 depending on the particular flag, SETZ sets the byte register to 1 if the zero flag is set for example.

Mirno
Posted on 2004-03-10 16:43:27 by Mirno
That's a good oversight Mirno, :), and thanks again, i think i'll prove both alternatives, to see which is better, at later, making this program bigger i think it'll gonna be yours mirno :)... thanks JaiKMw
Posted on 2004-03-10 19:04:25 by JaiKMw
hmmm ...

a little bit off topic but also important: what about optimizing your
source code layout and arrangement?

I suggest to do this from now on. Time will come and your projects
may grow.

bye Miracle
Posted on 2004-03-10 19:49:20 by miracle
I think that's a good point, i don't understand too much that (I peak spanish, thats why my english its not too good), are ya referring about a well-structured program, with tab's, spaces, comments, procedures, and that :)
Posted on 2004-03-11 21:36:28 by JaiKMw
Hallo JaiKMw,

I'm not an english native speaker too. But from the very begining I started to
comment my code (in english). This helped me a lot and it makes it much easier
to share knowledge here and with programmers somewhere.

The way you layout your source code depends on your taste and preferences.
Find your own way. I think it is especialy important to comment each PROC.
A header with a brief description, the arguments to be passed, the registers being
trashed (if any) and the return value is very helpfull. Usually there is no need to
comment each line. Include comments for bugs you have fixed. Organize your
projects in more than one source code file. Play with OOP even for small projects.

But again find your own way. If you are able to understand your own source codes
written two or more years ago quickly you are on the bright side of coding.

Keep on coding. If you really think your source codes are worth to be printed on
a wall paper you got it :-)

regards Miracle
Posted on 2004-03-14 20:26:32 by miracle
Wow!, that sounds good, really, the wall paper! :), just to imagine that, hahah :), maybe i take your advice, yes, i know that's good, a few weeks, maybe 2, i wrote a simple program, and yesterday i didn't remember anything! jojoj, yes, i'll start commenting all!... Thanks... JaiKMw
Posted on 2004-03-15 22:32:14 by JaiKMw