Showing posts with label Assembly-language. Show all posts
Showing posts with label Assembly-language. Show all posts

Tuesday, 25 July 2017

Program to convert Decimal into Octal using 8086 assembler


Code for Program to convert decimal number to binary in Assembly Language


DIS MACRO STR
MOV AH,09H
LEA DX,STR
INT 21H
ENDM
DATA SEGMENT
    MSG2 DB "BINARY NUMBER IS : $"
    STR1 DB 20 DUP('$')
    STR2 DB 20 DUP('$')
    NO DW 100
    LINE DB 10,13,'$'
DATA ENDS

CODE SEGMENT
         ASSUME DS:DATA,CS:CODE
START:
         MOV AX,DATA
         MOV DS,AX
         LEA SI,STR1
         MOV AX,NO
         MOV BH,00
         MOV BL,2
      L1:DIV BL
         ADD AH,'0'
         MOV BYTE PTR[SI],AH
         MOV AH,00
         INC SI
         INC BH
         CMP AL,00
         JNE L1

         MOV CL,BH
         LEA SI,STR1
         LEA DI,STR2
         MOV CH,00
         ADD SI,CX
         DEC SI

      L2:MOV AH,BYTE PTR[SI]
         MOV BYTE PTR[DI],AH
         DEC SI
         INC DI
         LOOP L2

         DIS LINE
         DIS MSG2
         DIS STR2
         MOV AH,4CH
         INT 21H 
CODE ENDS
END START

;------
;OUTPUT
;------

    BINARY NUMBER IS : 1100100

Monday, 24 July 2017

TO CONVERT A STRING INTO UPPER CASE TO LOWERCASE

Code for TO CONVERT A STRING INTO UPPER CASE TO LOWERCASE in Assembly Language


        .MODEL SMALL
        .DATA

                MSG  DB  0DH,0AH, ' ENTER THE STRING :-----> :  $'
                MSG2 DB  0DH,0AH, ' YOUR STRING IS  :-----> :  $'
                STR1 DB  255 DUP(?)
                ONE  DB ?
                TWO  DB ?
          .CODE

BEGIN:
          MOV AX,@DATA
          MOV DS,AX

          LEA DX,MSG
          MOV AH,09H
          INT 21H

          LEA SI,STR1
          MOV AH,01H

READ:
          INT 21H
          MOV BL,AL

          CMP AL,0DH
          JE  DISPLAY

          XOR AL,20H
          MOV [SI],AL
          INC SI

          ;CMP BL,0DH
          JMP READ
          


DISPLAY:

          MOV AL,'$'
          MOV [SI],AL

          LEA DX,MSG2
          MOV AH,09H
          INT 21H


          LEA DX,STR1
          MOV AH,09H
          INT 21H



         ; MOV AH,4CH
         ; INT 21H
          .EXIT



END BEGIN 

;**********************************OUTPUT******************************
;ENTER THE STRING :-----> SAMIR nihar KIRTAN
;YOUR STRING IS  :-----> samir NIHAR kirtan

Saturday, 22 July 2017

An Assembly program for finding the largest number in array of 10 elements


 

Assembly program self written

Now we will write another Assembly program for finding the largest number in array of 10 elements. 
First variables will be the one which will hold the value discovered as the Largest of All the Numbers in Array list and it will be LARGE and Second will be the one which will hold the values present in the Given Numbers in Array list and it will be array ARR. Other variables will be holding Length of the Array and it will be LEN, So in all Two variables.
The identified variables areARR, LEN and LARGE.
First Line – DATA SEGMENT
DATA SEGMENT is the starting point of the Data Segment in a Program and DATA is the name given to this segment and SEGMENT is the keyword for defining Segments, Where we can declare our variables.
Next Line – ARR DB 1,4,2,3,9,8,6,7,5,10
     LEN DW $-ARR
     LARGE DB ? 
ARR DB 1,4,2,3,9,8,6,7,5,10 this line is a declaration of 8-bit Numbers Array initialized with 1,4,2,3,9,8,6,7,5,10 the numbers are seperated by Comma (,). LEN DW $-ARR is used to Save the Length of the Array which will be generated by$-Name of the array i.e. $-ARR.We are initializing LARGE DB ? to ? (? stands for blank value).Detailed explanation is given below.
Next Line – DATA ENDS
DATA ENDS is the End point of the Data Segment in a Program. We can write just ENDS But to differentiate the end of which segment it is of which we have to write the same name given to the Data Segment.
Now, Selection of data type is DBdata type the numbers which we are adding will be integers so DB is sufficient.
Source code   
 DATA SEGMENT
     ARR DB 1,4,2,3,9,8,6,7,5,10
     LEN DW $-ARR
     LARGE DBDATA ENDS
 In Assembly programming, the variable are all defined by bytes only.
DB – Define Byte  (Size – 1 Byte)
DW – Define Word  (Size – 2 Byte)
DD – Define Double word  (Size -  4 Bytes)
DQ – Define Quad word  (Size – 8 Bytes)
DT – Define Ten Bytes  (Size – 10 Bytes)
NUMBER SYSTEM in Assembly Programming is Decimal, Octal, Hexadecimal, Binary.
In the Program, We are entering the values for the variables and Do arithmetical Operations like Addition, Subtraction, Multiplication and Division So the Computer should understand which kind of Number is entered. Hence there is a different letters for different Number Systems. Oor o stands for Octal, H or hstands for Hexadecimal, B or bstands for Binary, D or d stands for Decimal. By default type of numbering system is Decimal. If you do not specify any letter then the number is understood to be Decimal (By default).
Source code   
DATA SEGMENT
     ARR DB 1,4,2,3,9,8,6,7,5,10
     LEN DW $-ARR
     LARGE DBDATA ENDS
CODE SEGMENT 
        ASSUME DS:DATA CS:CODE
START:
        MOV AX,DATA
        MOV DS,AX
           
        LEA SI,ARR
       
        MOV AL,ARR[SI]
        MOV LARGE,AL
               
        MOV CX,LEN
REPEAT:
        MOV AL,ARR[SI]
        CMP LARGE,AL
        JG NOCHANGE
       
        MOV LARGE,AL
NOCHANGE:
        INC SI
        LOOP REPEAT
     
        MOV AH,4CH
        INT 21H     
CODE ENDS
END START
Explanation : 
In this Assembly Language Programming, A single program is divided into four Segments which are 1. Data Segment, 2. Code Segment, 3. Stack Segment, and 4. Extra  Segment. Now, from these one is compulsory i.e. Code Segment if at all you don’t need variable(s) for your program.if you need variable(s) for your program you will need two Segments i.e. Code Segment and Data Segment.
Next Line –CODE SEGMENT
CODE SEGMENT is the starting point of the Code Segment in a Program and CODE is the name given to this segment and SEGMENT is the keyword for defining Segments, Where we can write the coding of the program.
Next Line –     ASSUME DS:DATA CS:CODE
In this Assembly Language Programming, their are Different Registers present for Different Purpose So we have to assume DATA is the name given to Data Segment register and CODE is the name given to Code Segment register (SS,ES are used in the same way as CS,DS )
Next Line – START:
START is the label used to show the starting point of the code which is written in the Code Segment. : is used to define a label as in C programming.
Next Line – MOV AX,DATA
MOV DS,AX
After Assuming DATA and CODE Segment, Still it is compulsory to initialize Data Segment to DS register.  MOV is a keyword to move the second element into the first element. But we cannot move DATA Directly to DS due to MOV commands restriction, Hence we move DATA to AX and then from AX to DS. AX is the first and most important register in the ALU unit. This part is also called INITIALIZATION OF DATA SEGMENT and It is important so that the Data elements or variables in the DATA Segment are made accessable. Other Segments are not needed to be initialized, Only assuming is enhalf.
Next Line – LEA SI,ARR
LEA SI,ARR in this LEA stands for LOAD EFFECTIVE ADDRESS and it loads the effective address of second element into the first element.  This same code can be interchangably written as MOV DX, OFFSET PRICE where OFFSET  means effective address and MOV means move  second element into the first element. Here Base Address of variable PRICE is loaded in DX register.
Next Line – MOV AL,ARR[SI]
        MOV LARGE,AL
MOV AL,ARR[SI]  means move value of Array ARR in index of SI register to AL register. MOV LARGE,AL is to move AL register (First value in Array) to LARGE variable as we want to compare it with All the Array elements.
Next Line – MOV CX,LEN
 MOV CX,LEN is used to move or assign value 8 (Length of Array) to  CX. In assembly programming language we have a LOOP instruction. This works with two other helpers which are Label and Counter. The Loop start with LABEL and ends with LOOP instruction with the same LABEL name with it. the execution of the Loop depends on the value in CX register ( CX is also Called COUNTER).
Next Line – REPEAT:
REPEAT: is a LABEL and all the words ending in colon (:).
Next Line – MOV AL,ARR[SI]
MOV AL,ARR[SI] is to move value of Array ARR in index of SI register to AL register (Different values in Array). As we want to compare All elements with variable LARGE.
Next Line – CMP LARGE,AL
        JG NOCHANGE
CMP LARGE,AL  is used to compare AX register with 9 and JG NOCHANGE jump if AL is greater to the respective LABEL NOCHANGE. The result of Comparision is not stored anywhere, but flags are set according to result.  is Short Jump if first operand is Greater then second operand (as set by CMP instruction). Signed. SECOND is the label where the compiler will JUMP.
Next Line – MOV LARGE,AL 
MOV LARGE,AL is to move AL register (larger value in Array) to LARGE variable.
Next Line – NOCHANGE:
NOCHANGE: is a LABEL and all the words ending in colon (:).
Next Line – INC SI
INC SI will increment the Address value present in SI register. Here we are using SI register as a SOURCE INDEX which holds the Address of Array elements to Cover all the elements in Array.
Next Line – LOOP REPEAT
LOOP REPEAT  This end of loop. In assembly programming language we have a LOOP instruction. This works with two other helpers which are Label and Counter. The Loop start with LABEL and ends with LOOP instruction with the same LABEL name with it. the execution of the Loop depends on the value in CX register ( CX is also Called COUNTER).
Next Line – EXIT: MOV AH,4CH
      INT 21H
The above two line code is used to exit to dos or exit to operating system. Standard Input and Standard Output related Interupts are found in INT 21H which is also called as DOS interrupt. It works with the value of AH register, If the Value is 4ch, That means Return to Operating System or DOS which is the End of the program.
Next Line – CODE ENDS
CODE ENDS is the End point of the Code Segment in a Program. We can write just ENDS But to differentiate the end of which segment it is of which we have to write the same name given to the Code Segment.
Last Line – END START
END START is the end of the label used to show the ending point of the code which is written in the Code Segment.
Note :- In this Assembly Language Programming, We have Com format and EXE format. We are Learning in EXE format only which simple then COM format to understand and Write. We can write the program in lower or upper case, But i prepare Upper Case.


Saturday, 15 July 2017

Write and run a program using 8086 assembly language that multiplies two 8-bit numbers stored in two consecutive memory locations. The result of multiplication should be moved to DX register



DATA SEGMENT
    NUM1 DW 5H
    NUM2 DW 11H      
DATA ENDS

CODE SEGMENT
START:

    ASSUME CS:CODE, DS:DATA 
    MOV AX, DATA
    MOV DS, AX



    MOV AX, NUM1   
    MOV CX, NUM2 
    MUL CX
    MOV DX, AX
    
    MOV AX, 4C00H
    INT 21H  
      
CODE ENDS

END START

Write and run a program using 8086 assembly language that finds if the value stored in AL register is more than a value stored in a memory location; if it is more then AL register is cleared, otherwise AL register remains unchanged



DATA SEGMENT
    NUM DB 15H 
DATA ENDS

CODE SEGMENT
START:

    ASSUME CS:CODE, DS:DATA 
    MOV AX, DATA
    MOV DS, AX

    MOV AL, 9H
    MOV BL, NUM
    
    CMP AL,BL
    JG RESULT
    MOV AH, 4CH
    INT 21H
     
    
    RESULT: 
    MOV AL, 00000000B

    
    MOV AH, 4CH
    INT 21H  
      
CODE ENDS

END START

Write and run a program using 8086 assembly language that checks if the values stored in AL register and BL register are same. If both the values are same, the program output is “SAME”, otherwise it outputs nothing.

DATA SEGMENT NUM1 DB 15H NUM2 DB 15H MESSAGE db "SAME $" DATA ENDS CODE SEGMENT START: ASSUME CS:CODE, DS:DATA MOV AX, DATA MOV DS, AX MOV AL, NUM1 MOV BL, NUM2 CMP AL, BL JE RESULT RESULT: MOV DX, OFFSET MESSAGE MOV AH, 09H INT 21h MOV AX, 4C00H INT 21H CODE ENDS END START

Write and run a program using 8086 assembly language to find the smaller of two values stored in two different memory locations.

DATA SEGMENT
    NUM1 DB 15H
    NUM2 DB 9H
    SMALL DB ?
DATA ENDS

CODE SEGMENT
START:

    ASSUME CS:CODE, DS:DATA 
    MOV AX, DATA
    MOV DS, AX

    MOV AL, NUM1
    MOV BL, NUM2
    
    CMP AL, BL
    JLE RESULT
    
    MOV SMALL, BL
    
    MOV AX, 4C00H
    INT 21H  
    
    RESULT: MOV SMALL, AL
    
    MOV AX, 4C00H
    INT 21H    
CODE ENDS

END START

Thursday, 29 June 2017

X86 some tricks Assembly Language

Some very nice tricks for assembly programmers.
The hints show many particular, unknown and not-really-documented features with coding examples. They are of interest for all asm programmers from a medium level upwards.

The examples contain:

- 16bit vs 32bit addressing intro
- TRICK #1675301, MOV doesn't affect flags
- FLAGS and conditional jumps
- BT,BTC,BTS,BTR, bitwise commands
- BSWAP reg32, command example
- SIGN EXTENSION ENCODING 
- LAHF and SAHF instructions
- INC/DEC reg16/32
- EXTRA REGISTERS
- LEA command
shopping here on Amazon One plus 5




X86 Tips And Tricks
Laura Fairhead (April 2000)


32bit CODE

    I find it strange that an awful lot of ASM programmers who write
real-mode code seem to think that they (i) have to be 8086 compatible?
(ii) can only use 16bit functions.

    The first point is just a disease but the 2nd I think is due to
misinformation.

    In real-mode you have access to ALMOST all of the functionality of
the processor, in fact you typically have MORE access than the average
p-mode program (because the O/S will block you).

    Worse still it has been common knowledge for a long time now that
you can even access the WHOLE of memory (that is ALL 4GB) without
any help from special drivers. (Mind you you do have to toggle that
bit in CR0 albeit momentarily....)

    Any assembler will assemble code that uses 32-bit operand=size
or address-size by adding the prefixes 066h and 067h for you. Of course
this is the hit, you add one byte each time you access a 32-bit register,
but the same goes if you were accessing a 16-bit register in 32-bit code.

    Apart from using 32-bit registers/operands you also have access
to a 32-bit address size. This holds so many benefits, for example
if you want to access some data on the stack you DONT have to do that
MOV BP,SP rubbish just:-

    MOV AX,[ESP+somedisplacement]

    

TRICK #1675301

    One of the notable deficiencies of the x86 architecture is that a
MOV does not effect the flags. This is the most natural state of affairs
since we have an instant test for zero/sign.

    One of the ways around:-

        MOV reg,data
        AND reg,reg
        JZ wherever
    
        becomes....
    
        ADD regX,data
        JZ wherever

    Where regX was=0, adding the data is equivalent to a MOV that sets
the flags for us.

    Do you like writing "cryptic" code ? :-

        XOR reg,reg
        ADD reg,data
        JZ wherever

    So what's the point other than to make your code "unreadable" ?

    Aha!, secrets....


FLAGS

    One of the keys to understanding assembly language is the flags.
Efficient use of the flags is also the way to write very compact code.
I remember the major block I had for grasping assembly was the conditional
branch, in particular:-

        JE where_to_go

(it was actually BEQ, the equivalent 6502 instruction, but the principle
is the same.)

    Here I remember asking the question, yes but jump if equal WHAT??!
The fact is that most people seem to view CMP and JE/JNE as inseperable
partners and they are not. This is machine code-- it is NOT a language,
all we have is the machine state.

        CMP AL,1
        SBB AH,AH

    There is a synonym in x86 for JE called JZ, also its partner JNE can
be called JNZ. I always use these synonymns for the basic reason that
the name more accurately describes what the instruction actually does
(as opposed to what it is generally used for). JZ => Jump if Zero, the
JZ instruction branches iff ZF=1, there is no EQUAL !!

    So:-
        DEC AX
        MOV AX,[another_value]
        JZ gohereifaxwas1

    will branch to gohereifaxwas1 if AX was equal 1 at the start, since
the DEC instruction will set the zero flag if it results in a 0, and
the MOV doesn't affect the flags (many of the intel instructions don't).


BT,BTC,BTS,BTR

    When you have arrays where the elements can only take two possible
values it is best to use bits. The x86 from 386+ has very nice bit test
instruction which allows you to address individual bits without messing
about. God knows why but a lot of ASM programmers are still programming
8086 compatible code, didn't someone tell them the 286 is dead?

    BT [mem],AX   Tests the AX'th bit of a bit array that starts at mem.
You have to use a 16/32bit register but otherwise this instruction is
extremely useful; it sets the carry flag to the previous state of the bit.
The others BTC,BTS,BTR also complement, set, and reset the respective bit
(AFTER getting it into the CF!).

    Do you know how many C instructions are needed to perform this
operation ? 


BSWAP reg32

    Although documented as being useful for endian conversion this
instruction also allows the programmer to make the hi-word of a 32bit
register more accessible.

        EAX
before  1   2   3   4

after   4   3   2   1

    Of course you get all your words al-reverso, but if you were dealing
with 4-bytes of data now you have the other 2 in AL and AH.

    For example if you are copying DS:SI->ES:DI but each byte in the target
you want to be 0FFh if the source was non-zero and 000h otherwise, it is
best to do it in dwords:-

    LODSD
    CMP AL,1
    SBB AL,AL
    CMP AH,1
    SBB AH,AH
    BSWAP EAX
    CMP AL,1
    SBB AL,AL
    CMP AH,1
    SBB AH,AH
    BSWAP EAX
    STOSD

    Not the MOST efficient way, granted, but you can see my point. For
further examples of BSWAP in action take a look at the graphic primitives
in some decent demo source.


SIGN EXTENSION ENCODING

    The instruction family CMP/SUB/OR/XOR/AND/ADD/SBB/ADC have an encoding
where the immediate 8-bit source operand is sign extended to the destination
size. This can be used to set word/dword memory location to 0 or -1 using
less bytes than the equivalent MOV :-

    sets memory to -1
82 xx FF            OR WORD PTR [mem],-1
82 xx FF            OR DWORD PTR [mem],-1

    equivalent MOVs:
C7 xx FF FF         MOV WORD PTR [mem],-1
C7 xx FF FF FF FF   MOV DWORD PTR [mem],-1

    sets memory to 0
82 xx 00            AND WORD PTR [mem],0
82 xx 00            AND DWORD PTR [mem],0

    equivalent MOVs:
C7 xx 00 00         MOV WORD PTR [mem],0
C7 xx 00 00 00 00   MOV DWORD PTR [mem],0



LAHF


    LAHF/SAHF are under-used instructions which offer a wonderful service.

    LAHF copies the least significant byte of EFLAGS to the AH register,
likewise SAHF copies the AH register to the least significant byte of
EFLAGS.

    The least significant byte of EFLAGS is:-

        b7 b6 b5 b4 b3 b2 b1 b0
        SF ZF x  AF x  PF x  CF

    So you can use this to save all of the general-purpose flags minus OF.
This can be used instead of PUSHF/POPF in a lot of cases, you don't save
any bytes but your code will be quicker as you are not accessing memory
anymore.



INC/DEC reg16/32

    There is a special encoding for INC/DEC that only takes 1 byte. This
is INC/DEC reg16 (or INC/DEC reg32 in 32-bit mode). There are many places
which you can use this, note that :-

        INC AX
    
        is the same as (*)
    
        INC AL
    
        JNZ ko
        INC AH
ko:

    So if we don't care about AH, we can substitute INC AL for INC AX, and
save a byte.

(*) (well, okay not the flags but you get my point)

    The same thing works for DEC :-

        DEC AX
    
        is the same as
    
        DEC AL
    
        CMP AL,0FFh
        JNZ ko
        DEC AH
ko:

    So if we don't care about AH, we can substitue DEC AL for DEC AX, and
save another byte.

    If you know that AL will never = 0FFh, then INC AX is doing the same
operation as INC AL.



EXTRA REGISTERS

    Running out of registers? You are probably just not using them
efficiently.

    So we have EAX,EBX,ECX,EDX,ESI,EDI,EBP

    Yes 32-bit, I only rarely even see people use these in 16-bit code,
don't know why because they are still there. Okay so you waste a byte with
that operand prefix, true. 7*32bits, thats 224bits, almost enough to
write a tiny program!! Don't believe me? Think of a bit as a matchbox
which can have a pebble in it or not, just imagine how much state information
you have with 224 of these, could you fit them all on the kitchen table?

    It's really amazing what you can do with just 3 registers let alone,
how many??, XCHG comes in very handy you know.

    TRAP #5466332

    Oh! Do watch out!

    I didn't warn you; when an interrupt occurs the processor will only
save the 16-bit register set to the stack. So if your interrupt routine
uses any 32-bit registers it must save/restore them itself. Or you could
catch a bug like Windoze did.

    JUST PLAIN BAD ?

    I am a horror really; do you know that I once used SP as an extra
register. Naughty, naughty... Of course when you get an interrupt, SPLAT!,
all that stack space used by the routine is actually writing over your
most important data structures.

    Using SP/ESP is really fine though if and only if you don't use the
stack. So NO interrupts. Even the hottest hackers start to cringe if
they have to get this dirty, it's just PLAIN INELEGANT, however it is
important to be aware of possibilities even if you are sure you are
not going to use them.
   

    SO ARE THERE REALLY ANY EXTRA REGISTERS ?

    Oh yes, right in front of your eyes. DS, ES, FS, GS. 4 lovely 16-bit
chunks of memory right in the processor core. Still I'm not absolutely
sure anymore whether its worth it to use these. The way the processors
are being built these days it would probably have been ( a lot ) quicker
to use the stack frame....

    MOV AX,0
lop:
    MOV FS,AX
    MOV AH,2
    MOV DL,030h
    INT 021h

    MOV AX,FS
    INC AL
    JNO lop

    Okay so you've run out of registers in that inner loop. Your trying
to blit your super-rotating-warping sprites at the speed of light and
it's no good if we get all those L1 cache accesses (which do take TIME).
Other places? Well how many of these registers you need are going to be
constant for the period of the loop? I bet you there are at least a few.
Here is where we get off:-

   *LOOP START*
    .
    .
    .
    MOV AX,[BX]
    ADD AX,CX
    .
    .
    .
   *LOOP END*

    say this is part of your loop, but you know that CX is never going to
change. What a waste !!

   *INITIALISATION*
    .
    .

    MOV WORD PTR CS:[k1],konstant
    .
    .
    JMP SHORT $+2

   *LOOP START*


    .
    .
    .
    MOV AX,[BX]
k1  EQU $+2
    ADD AX,0AA55h
    .
    .
    .
   *LOOP END*

    
    You just saved a register. The JMP SHORT is a just-in-case, if the
code at offset k1 in the loop is in the prefetch queue when it is modified
you could end up with the processor modifying the memory but not the
prefetch queue, so the 1st time around the loop executes improperly.
This doesn't happen post-Pentium since the Pentium flushes the prefetch
queue if you write to it (oh, all those debugger traps that are now
going wrong....).

LEA

    LEA is useful for so many things, I find it quaint now that on first
encountering it I thought all it was was a MOV instruction.

    LEA allows you to access no less than 3 adders in the CPU simultaneously.
One of these adders can be scaled by 1,2,4,8 allowing multiplication.

    There are two address formats with x86 you can use BOTH regardless of
the code size.

    LEA reg16/32,EA

    If the address is 32-bit and the operand size is only 16-bit, the
effective address gets truncated into the destination. If the address
is 16-bit and the operand size is 32-bit then the effective address gets
zero-extended into the destination. This later point allows you to get
a MOVZX instruction on immediate values, ala:-

    LEA EAX,[01234h]

    which is equivalent to:-

    MOV EAX,01234h

    only the LEA is taking a byte less, as the data is represented as a
WORD only.

    LEA can give you various multiples of a register

    LEA EAX,[EAX*2]                 *2
    LEA EAX,[EAX*2+EAX]             *3
    LEA EAX,[EAX*4]                 *4
    LEA EAX,[EAX*4+EAX]             *5
    LEA EAX,[EAX*8]                 *8
    LEA EAX,[EAX*8+EAX]             *9

    Of course the source and destination don't have to be the same so
you can get an extra MOV out of it. In addition you have the displacement
factor, so instead of:-

    MOV EBX,EAX
    ADD EAX,EAX
    ADD EAX,EBX
    ADD EAX,01234h

    You can do:

    LEA EAX,[EAX*2+EAX+01234h]

    Pretty impressive !

    LEA doesn't affect the flags, so if you need to add without affecting
flags here is your instruction.

    CMP [SI],EAX
    LEA SI,[SI+4]
    JZ wherever


    As an aside it is at this point where MASM becomes rather embarrased.
It will not assemble the following instruction:-

    LEA EAX,[01234h]

    Instead requires you to put:-

    LEA EAX,DWORD PTR DS:[01234h]

    Which makes your code look right up the garden path (what the hell
does the DWORD and DS: have to do with this instruction??).

    But then again MASM specializes in bulk and gimmicks rather than
precision in functionality.

Sunday, 16 April 2017

All Interrupt for Emu8086(Assembly language)

The list of all interrupts that are currently supported by the emulator.
These interrupts should be compatible with IBM PC and all generations of x86,
original Intel 8086 and AMD compatible microprocessors, however Windows XP may
overwrite some of the original interrupts.
Quick reference:
the short list of supported interrupts with descriptions:
INT 10h / AH = 0 - set video mode.
input:
AL = desired video mode.
these video modes are supported:
00h - text mode. 40x25. 16 colors. 8 pages.
03h - text mode. 80x25. 16 colors. 8 pages.
13h - graphical mode. 40x25. 256 colors. 320x200 pixels. 1 page.
example:
mov al, 13h
mov ah, 0
int 10h
INT 10h / AH = 01h - set text-mode cursor shape.
input:
CH = cursor start line (bits 0-4) and options (bits 5-7).
CL = bottom cursor line (bits 0-4).
INT 10h/00h
INT 10h/01h
INT 10h/02h
INT 10h/03h
INT 10h/05h
INT 10h/06h
INT 10h/07h
INT 10h/08h
INT 10h/09h
INT 10h/0Ah
INT 10h/0Ch
INT 10h/0Dh
INT 10h/0Eh
INT 10h/13h
INT 10h/1003h
INT 11h
INT 12h
INT 13h/00h
INT 13h/02h
INT 13h/03h
INT 15h/86h
INT 16h/00h
INT 16h/01h
INT 19h
INT 1Ah/00h
INT 20h
INT 21h
INT 21h/01h
INT 21h/02h
INT 21h/05h
INT 21h/06h
INT 21h/07h
INT 21h/09h
INT 21h/0Ah
INT 21h/0Bh
INT 21h/0Ch
INT 21h/0Eh
INT 21h/19h
INT 21h/25h
INT 21h/2Ah
INT 21h/2Ch
INT 21h/35h
INT 21h/39h
INT 21h/3Ah
INT 21h/3Bh
INT 21h/3Ch
INT 21h/3Dh
INT 21h/3Eh
INT 21h/3Fh
INT 21h/40h
INT 21h/41h
INT 21h/42h
INT 21h/47h
INT 21h/4Ch
INT 21h/56h
INT 33h/0000h
INT 33h/0001h
INT 33h/0002h
INT 33h/0003h

When bit 5 of CH is set to 0, the cursor is visible. when bit 5 is 1, the cursor is not
visible.
; hide blinking text cursor:
mov ch, 32
mov ah, 1
int 10h
; show standard blinking text cursor:
mov ch, 6
mov cl, 7
mov ah, 1
int 10h
; show box-shaped blinking text cursor:
mov ch, 0
mov cl, 7
mov ah, 1
int 10h
; note: some bioses required CL to be >=7,
; otherwise wrong cursor shapes are displayed.
INT 10h / AH = 2 - set cursor position.
input:
DH = row.
DL = column.
BH = page number (0..7).
example:
mov dh, 10
mov dl, 20
mov bh, 0
mov ah, 2
int 10h
INT 10h / AH = 03h - get cursor position and size.
input:
BH = page number.
return:
DH = row.
DL = column.
CH = cursor start line.
CL = cursor bottom line.
INT 10h / AH = 05h - select active video page.
input:
AL = new page number (0..7).
INT 10h / AH = 06h - scroll up window.
INT 10h / AH = 07h - scroll down window.
input:
AL = number of lines by which to scroll (00h = clear entire window).
BH = attribute used to write blank lines at bottom of window.
CH, CL = row, column of window's upper left corner.
DH, DL = row, column of window's lower right corner.
INT 10h / AH = 08h - read character and attribute at cursor position.
input:
BH = page number.
return:
AH = attribute.
AL = character.
INT 10h / AH = 09h - write character and attribute at cursor position.
input:
AL = character to display.
BH = page number.
BL = attribute.
CX = number of times to write character.
INT 10h / AH = 0Ah - write character only at cursor position.
input:
AL = character to display.
BH = page number.
CX = number of times to write character.
INT 10h / AH = 0Ch - change color for a single pixel.
input:
AL = pixel color
CX = column.
DX = row.
example:
mov al, 13h
mov ah, 0
int 10h ; set graphics video mode.
mov al, 1100b
mov cx, 10
mov dx, 20
mov ah, 0ch
int 10h ; set pixel.
INT 10h / AH = 0Dh - get color of a single pixel.
input:
CX = column.
DX = row.
output:
AL = pixel color
INT 10h / AH = 0Eh - teletype output.
input:
AL = character to write.
this functions displays a character on the screen, advancing the cursor and scrolling the screen
as necessary. the printing is always done to current active page.
example:
mov al, 'a'
mov ah, 0eh
int 10h
; note: on specific systems this
; function may not be supported in graphics mode.
INT 10h / AH = 13h - write string.
input:
AL = write mode:
bit 0: update cursor after writing;
bit 1: string contains attributes.
BH = page number.
BL = attribute if string contains only characters (bit 1 of AL is zero).
CX = number of characters in string (attributes are not counted).
DL,DH = column, row at which to start writing.
ES:BP points to string to be printed.
example:
mov al, 1
mov bh, 0
mov bl, 0011_1011b
mov cx, msg1end - offset msg1 ; calculate message size.
mov dl, 10
mov dh, 7
push cs
pop es
mov bp, offset msg1
mov ah, 13h
int 10h
jmp msg1end
msg1 db " hello, world! "
msg1end:

INT 10h / AX = 1003h - toggle intensity/blinking.
input:
BL = write mode:
0: enable intensive colors.
1: enable blinking (not supported by the emulator and windows command
prompt).
BH = 0 (to avoid problems on some adapters).
example:
mov ax, 1003h
mov bx, 0
int 10h

bit color table:
character attribute is 8 bit value, low 4 bits set fore color, high 4 bits set background color.
note: the emulator and windows command line prompt do not support background blinking,
however to make colors look the same in dos and in full screen mode it is required to turn off
the background blinking.
HEX BIN COLOR
0 0000 black
1 0001 blue
2 0010 green
3 0011 cyan
4 0100 red
5 0101 magenta
6 0110 brown
7 0111 light gray
8 1000 dark gray
9 1001 light blue
A 1010 light green
B 1011 light cyan
C 1100 light red
D 1101 light magenta
E 1110 yellow
F 1111 white
note:
; use this code for compatibility with dos/cmd prompt full screen mode:
mov ax, 1003h
mov bx, 0 ; disable blinking.
int 10h