News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Memory Map

Started by zak100, February 19, 2010, 06:21:07 PM

Previous topic - Next topic

dedndave

it's kind of fun Zulfi
i get to keep my hand in 16-bit code so i don't forget it all - lol
but, you should try to understand the code we provide - learn from it
it would be great to see you post good code you have written yourself  :bg

FORTRANS

Quote from: zak100 on March 08, 2010, 06:49:30 PM

quote

Call with DS:SI pointing to a QWORD (eight bytes) to be
; displayed as hexadecimal.
/quote

Thanks for your code. I have one prob. which is stated in the comment. In my code, ES:DI points to the QWORD which is natural after executing 15h. This comment means I cant use your code.

Hi Zulfi,

   Try changing:


        LODSB           ; Get a byte.


   To something like:


        MOV     AL,ES:[DI]      ; Get a byte
        DEC     DI


   And PUSH/POP DI instead of SI.  That _should_ work.
It is handy to use LODSB, which defaults to DS:SI.


Regards,

Steve

dedndave

you could also fix it by moving segment values around in the segment registers by using push and pop

zak100

Hi,
I would try. Thanks for guidance and encouragement.

Zulfi.

zak100

Hi,
What is the purpose of this DB?



DB      0D4H, 10H       ; Isolates high nybble in AH and low
                        ; nybble in AL.





Zulfi.

dedndave

0D4h,0Ah is the opcode for the AAM instruction (ASCII adjust multiply)
it essentially divides the value in AL by 10 and places the quotient in AH and the remainder in AL

by modifying the opcode to 0D4h,10h, we can alter the AAM instruction to divide by 16 instead of 10
so, it splits the lower 4 bits from the upper 4 bits
it is an "undocumented" opcode that has worked since the 8088 - intel and amd have always supported it in new CPUs

it saves some code because it is small
AAM is not a particularly fast instruction, though
on pentiums it is about 18 clock cycles - a mov/shift/and combination is probably slightly faster
on the 8088, it was 84 clock cycles if i remember correctly

if you want speed, code it the other way
if you want small size, use AAM   :bg

MichaelW

Zulfi,

DB is a data definition directive that allocates one or more unsigned bytes. It's the same directive that you would use in the data segment, but here it is used in the code segment to "synthesize" a form of the AAM instruction that behaves differently than the normal form. You can walk through it in DEBUG to see how it behaves:

-a

0B10:0100 mov al, 63      ; load 99d into AL

0B10:0102 aam             ; convert to unpacked BCD in AX

0B10:0104 mov al, 63      ; load 99d into AL

0B10:0106 db  d4 10       ; convert to unpacked BCH in AX

0B10:0108 nop             ; this is just a filler

0B10:0109

-r

AX=0000  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000 
DS=0B10  ES=0B10  SS=0B10  CS=0B10  IP=0100   NV UP EI PL NZ NA PO NC
0B10:0100 B063          MOV AL,63                             
-t 4


AX=0063  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000 
DS=0B10  ES=0B10  SS=0B10  CS=0B10  IP=0102   NV UP EI PL NZ NA PO NC
0B10:0102 D40A          AAM                                   

AX=0909  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000 
DS=0B10  ES=0B10  SS=0B10  CS=0B10  IP=0104   NV UP EI PL NZ NA PE NC
0B10:0104 B063          MOV AL,63                             

AX=0963  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000 
DS=0B10  ES=0B10  SS=0B10  CS=0B10  IP=0106   NV UP EI PL NZ NA PE NC
0B10:0106 D410          AAM 10                                 

AX=0603  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000 
DS=0B10  ES=0B10  SS=0B10  CS=0B10  IP=0108   NV UP EI PL NZ NA PE NC
0B10:0108 90            NOP                                   
-q


Note that I added the comments after I captured the output. Also note that I labeled the output for the second form as BCH (Binary-Coded Hex) for want of a better term.

eschew obfuscation

FORTRANS

Quote from: dedndave on March 09, 2010, 07:34:02 PM
...
it saves some code because it is small
AAM is not a particularly fast instruction, though
...
if you want speed, code it the other way
if you want small size, use AAM   :bg

Hi,

   I mostly wanted to show another way to do the job.  And
if you are going to call DOS or BIOS to emit a character, the
speed is moot.  I probably underdocumented it though.

Regards,

Steve N.

dedndave

i was just trying to give Zulfi a heads up on using an undocumented opcode - lol
every now and then, he is likely to see some hard-coded instruction - good to know what it is

zak100

Hi,
I cant understand following set of instruction:

CMP     AL,10   ; Convert to ASCII hex using "magic".
        SBB     AL,69H
        DAS

I have found that DAS subtract 6 or 60 h depending on the value of lower and upper nibble in AL.
What is the significance of 69H.
I need an example in this regard.

Thanks for helping me.

Zulfi.

dedndave

#40
the CMP AL,10h sets or clears the carry flag for the SBB instruction
the DAS instruction acts like this (copied from Randy Hyde's AoA)

if ( (al and 0Fh) > 9 or (AuxC = 1)) then
        al := al -6
        AuxC = 1
endif
if (al > 9Fh or Carry = 1) then
        al := al - 60h
        Carry := 1              ;Set the Carry flag
endif


so, there is no "magic", Zulfi - lol
in computers, there rarely is
microwave circuits - now, that's another subject   :P

zak100

Thanks. Kindly say something about 69h also.

Zulfi.

dedndave


; AL = 0 to 0Fh

        cmp     al,0Ah
        sbb     al,69h
        das

; AL = ASCII hexidecimal

; initial AL   CF after CMP   AL after SBB   AC after SBB   AL after DAS
;
;     0             CY             96h            AC             30h
;     1             CY             97h            AC             31h
;     2             CY             98h            AC             32h
;     3             CY             99h            AC             33h
;     4             CY             9Ah            AC             34h
;     5             CY             9Bh            AC             35h
;     6             CY             9Ch            AC             36h
;     7             CY             9Dh            AC             37h
;     8             CY             9Eh            AC             38h
;     9             CY             9Fh            AC             39h
;    0Ah            NC            0A1h            NA             41h
;    0Bh            NC            0A2h            NA             42h
;    0Ch            NC            0A3h            NA             43h
;    0Dh            NC            0A4h            NA             44h
;    0Eh            NC            0A5h            NA             45h
;    0Fh            NC            0A6h            NA             46h
;
; in this code, the carry flag is always set after the SBB instruction
; the auxilliary carry flag is similar to carry, but applies to the lower nybble of the result
;
; DAS pseudo-code:
;
; if ( (al and 0Fh) > 9 or (AuxC = 1)) then
;         al := al -6
;         AuxC = 1
; endif
; if (al > 9Fh or Carry = 1) then
;         al := al - 60h
;         Carry := 1
; endif

FORTRANS

Hi,

   Sorry Zulfi, I probably should not have said "magic".  But as
shown in my other posts, I have a defective sense of humor.
It probably should have said "This converts binary to ASCII,
but how this is done is too complex to fit in the margin".  The
69H just happens to work with the CMP, SBB, and DAS sequence.
(And that appears to be magic until you work out how it really works.)
dedndave shows exactly how that works out in his last post.  You
can walk through the code in DEBUG (or another debugger/emulator)
to see how it works for yourself.

Regards,

Steve


A:\>debug
-a
1673:0100 nop
1673:0102 cmp al,a
1673:0104 sbb al,69
1673:0106 das
1673:0107 jmp 100
1673:0109
-t4

AX=0000  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=1673  ES=1673  SS=1673  CS=1673  IP=0102   NV UP EI PL ZR NA PE NC
1673:0102 3C0A          CMP     AL,0A

AX=0000  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=1673  ES=1673  SS=1673  CS=1673  IP=0104   NV UP EI NG NZ AC PE CY
1673:0104 1C69          SBB     AL,69

AX=0096  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=1673  ES=1673  SS=1673  CS=1673  IP=0106   NV UP EI NG NZ AC PE CY
1673:0106 2F            DAS

AX=0030  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=1673  ES=1673  SS=1673  CS=1673  IP=0107   OV UP EI PL NZ AC PE CY
1673:0107 EBF7          JMP     0100
-rax
AX 0030
:9
-t5


   Repeat as necessary!

zak100

Hi,
I think it should help me. Thanks for giving me so much time.

Zulfi.