1. Do I have to null all segments, or just i need to null DS, ES, SS segments?
if org is 0x7C00 you "have to" zero DS.
because you use a "lodsb" which by default
loads from DS:SI ( "D"ata "S"egment :
"S"ource "I"ndex [ source pointer ] )
ES and SS is not necessary, but remember
it is good to have a known stack so put
SS:SP to somewhere ( not necessarily
0x0000:something ) and you also even
dont need to zero CS but because org
is 0x7C00, you need to zero it.
2. What means this line: mov sp,0xfffe ?
mov ax , 0 ( xor ax , ax )
mov ss , ax
mov sp , 0xFFFE
puts the stack to 0x0000:0xFFFE ( a really
good place for stack, but better in my
opinion is 0x9000:0xFFFE )
3. Why cld must be written in Print procedure?
lodsb does the following
mov al , [ DS:SI ]
if DF=clear SI++ else SI--
DF is direction flag ( in flags register. lodsb
increments SI if DF is zero, decrements if
it is set (1). CLD clears the direction flag
and thus lodsb loads and increments SI, you can
not trust the DF to be reset so you must clear
it on entry to "Print" yourself.
it would be a little funny but it IS possible to write
a string in reverse direction by first putting the SI to
the end of the string and using STD ( set DF ) instead
of CLD, who would ever want this is another question.