CHƯƠNG 1: MӢ ĐҪU ............................................................................................................................. 3
   1.1. NHҳC LҥI CÁC HӋ ĐӃM ......................................................................................................................... 3
      1.1.1. Các h͏ đ͇m ............................................................................................................................... 3
      1.1.2. Chuy͋n đ͝i s͙ giͷa các h͏ đ͇m ................................................................................................. 3
   1.2. VI Xӱ LÝ 8086, TұP LӋNH VÀ CÁC MODE ĐӏA CHӍ .................................................................................. 6
      1.2.1. Vi x͵ lý 8086 ............................................................................................................................ 6
      1.2.2. Các thanh ghi và mode đ͓a ch͑ trong 8086 ................................................................................ 7
      1.2.3. Các mode đ͓a ch͑ cͯa 8086 ..................................................................................................... 10
   1.3. NGҳT .............................................................................................................................................. 14
   1.4. GIӟI THIӋU VӅ HӧP NGӳ ..................................................................................................................... 16
      1.4.1. L̵p trình b̹ng hͫp ngͷ .......................................................................................................... 16
      1.4.2. Các bưͣc vi͇t chương trình hͫp ngͷ ....................................................................................... 17
      1.4.3. C̭u trúc m͡t chương trình hͫp ngͷ d̩ng segment đơn gi̫n .................................................... 19
      1.4.4. C̭u trúc cͯa m͡t chương trình segment d̩ng chu̱n ............................................................... 24
CHƯƠNG 2. LұP TRÌNH VӟI DEBUG ................................................................................................. 30
   2.1. TәNG QUAN VӅ DEBUG .................................................................................................................... 30
      2.1.1. Đ̿c đi͋m cͯa Debug............................................................................................................... 30
      2.1.2. Khͧi đ͡ng và thoát kh͗i Debug ............................................................................................... 30
   2.2. CÁC LӋNH CӫA DEBUG ..................................................................................................................... 30
      2.2.1. Nhóm các l͏nh biên so̩n chương trình.................................................................................... 30
      2.2.2. Nhóm các l͏nh d͓ch chuy͋n dͷ li͏u ......................................................................................... 32
      2.2.3. Nhóm l͏nh quan sát ................................................................................................................ 34
      2.2.4. Nhóm l͏nh thi hành chương trình ............................................................................................ 34
CHƯƠNG 3: CÁC LӋNH CӫA ASSEMBLY ......................................................................................... 36
   3.1 CÁC LӋNH VұN CHUYӇN Dӳ LIӋU ......................................................................................................... 36
   3.2 CAC LӋNH Sӕ HӑC .............................................................................................................................. 39
   3.3 CAC LӋNH THAO TAC MӭC BIT ........................................................................................................... 43
   3.4 CAC LӋNH THAO TAC VӟI DÃY (CHUӛI) ............................................................................................... 46
   3.5 CAC LӋNH NHҧY ± CHUYӇN DIӅU KHIӇN .............................................................................................. 48
   3.6 CAC LӋNH THAO TAC VӟI Cӡ VA DIӅU KHIӇN Bӝ.................................................................................... 50
CHƯƠNG 4 CHƯƠNG TRINH CON VA CHƯƠNG TRINH DA TӋP ................................................ 52
   4.1 THӫ TөC ± CHƯƠNG TRINH CON ......................................................................................................... 52
      4.1.1 Cơ ch͇ làm vi͏c cͯa chương trình con...................................................................................... 52
      4.1.2 C̭u trúc cͯa chương trình con ................................................................................................. 52
      4.1.3 V̭n đ͉ chuy͋n giao tham s͙ ..................................................................................................... 53
      4.1.4 V̭n đ͉ b̫o v͏ các thanh ghi .................................................................................................... 54
      4.1.5. M͡t s͙ ví dͭ ............................................................................................................................ 54
   4.2 CHƯƠNG TRÌNH ĐA TӋP ..................................................................................................................... 58
      4.2.1 L͏nh đi͉u khi͋n PUBLIC ......................................................................................................... 58
      4.2.2 L͏nh đi͉u khi͋n EXTERN......................................................................................................... 59
      4.2.3 L͏nh đi͉u khi͋n GLOBAL ....................................................................................................... 59
      4.2.4. T͏p INCLUDE và cách dùng................................................................................................... 62
      4.2.5 MACRO và v̭n đ͉ liên quan .................................................................................................... 65
      4.2.5.1. Chͱc năng ........................................................................................................................... 65
CHƯƠNG 5: CÁC THAO TÁC VӟI TӋP ............................................................................................... 70
   5.1 THҿ FILE (F ILE HANDLES) ................................................................................................................ 70
      5.1.1 Kh͙i đi͉u khi͋n file ± FCB (File Control Blocks)...................................................................... 70
      5.1.2 Th̓ file .................................................................................................................................... 70
   5.2. CAC DӏCH Vө DUNG THҿ FILE CӫA DOS VA CAC MÃ LӛI ...................................................................... 71
      5.2.1. Các d͓ch vͭ dùng th̓ file cͯa DOS .......................................................................................... 71
      5.2.2 Các mã l͟i tr̫ v͉ ..................................................................................................................... 82
CHƯƠNG 6 LIÊN KӃT GIӳA NGÔN NGӳ ASSEMBLY VӟI CÁC NGÔN NGӳ BұC CAO .............. 84
   6.1 Mӣ ĐҫU ............................................................................................................................................ 84
   6.2. LIÊN KӃT ASSEMBLY VӟI NGÔN NGӳ C............................................................................................... 84



                                                                                                                                                            1
6.2.1. Inline assembly trong C .......................................................................................................... 84
      6.2.2. Vi͇t tách bi͏t nhi͉u module trong C ........................................................................................ 85
      Khai báo cͯa ASM: Gi͙ng như đa t͏p thu̯n tuý .................................... Error! Bookmark not defined.
VҩN ĐӅ 2 ...................................................................................... ERROR! BOOKMARK NOT DEFINED.
   6.3 LIÊN KӃT ASSEMBLY VӟI NGÔN NGӳ PASCAL....................................................................................... 87
      6.3.1. Inline assembly trong Pascal................................................................................................... 87
      6.3.2. Inline assembly trong Pascal................................................................................................... 88




                                                                                                                                                2
Chương 1: MӢ ĐҪU

1.1. Nhҳc lҥi các hӋ đӃm

1.1.1. Các hӋ đӃm
     Trong cuӝc sӕng hàng ngày chúng ta thưӡng dùng hӋ cơ sӕ 10 ± hӋ đӃm
đưӧc hình thành tӯ 10 kí sӕ tӯ 0 đӃn 9 - đӇ biӇu diӉn các giá trӏ sӕ. ĐiӅu này rҩt
tӵ nhiên vì tӯ xa xưa con ngưӡi bình thưӡng đã biӃt dùng 10 ngón tay cӫa mình
đӇ như là mӝt công cө tính toán sơ đҷng.
     Trong thӃ giӟi máy tính thì khác, do máy tính đưӧc cҩu tҥo nên tӯ các mҥch
điӋn tӱ và các mҥch này chӍ có hai trҥng thái có điӋn và không có điӋn. Do đó đӇ
biӉu diӉn mӝt giá trӏ sӕ trong máy tính ngưӡi ta sӱ dөng hӋ đӃm cơ sӕ hai hay hӋ
đӃm nhӏ phân (Binary number system). Trong hӋ đӃm này chӍ tӗn tҥi hai chӳ sӕ 0
và 1 tương ӭng vӟi hai trҥng thái có điӋn và không có điӋn cӫa các mҥch điӋn tӱ.
     NӃu dùng hӋ cơ sӕ hai đӇ biӇu diӉn các sӕ có giá trӏ lӟn sӁ gһp bҩt tiӋn là sӕ
hӋ hai thu đưӧc quá dài, thí dө: 255 = 1111 1111
       ĐӇ viӃt kӃt quҧ biӉu diӉn các sӕ cho gӑn lҥi ngưӡi ta sӱ dөng các các hӋ
đӃm khác như hӋ cơ sӕ 8(bát phân) và hӋ cơ sӕ 16 (thұp lөc, hexa). Bҧng sau đây
trình bày mӝt sӕ hӋ đӃm cơ bҧn:
  HӋ đӃm                       Cơ sӕ    Sӕ kí sӕ và kí tӵ   Dҥng kí sӕ và kí tӵ
  Nhӏ phân (Binary)            2        2                   0,1
  Bát phân (Octal)             8        8                   0,1,2,3,4,5,6,7
  Thұp phân (Decimal)          10       10                  0,1,2,3,4,5,6,7,8,9
  Thұp lөc phân                16       16                  0,1,2,3,4,5,6,7,8,9,
  (Hexadecimal)                                             A,B,C,D,E,F
                                 Bҧng 1.1. Các hӋ đӃm cơ bҧn
     Ngoài ra, hӋ đӃm BCD còn đưӧc sӱ dөng đӇ biӇu diӉn các sӕ tӯ 0 đӃn 9 vӟi
4 bit (4 bit=1 nibble) nhӏ phân.

1.1.2. ChuyӇn đәi sӕ giӳa các hӋ đӃm
1.1.2.1. ChuyӇn đәi giӳa hӋ thұp phân và hӋ nhӏ phân
a. ChuyӇn tӯ hӋ thұp phân sang hӋ nhӏ phân
      Quy tҳc: Lҩy phҫn nguyên chia cho 2 và ghi lҥi phҫn dư, tiӃp tөc lҩy
thương chia cho 2 và ghi lҥi phҫn dư. Lһp lҥi quá trình cho đӃn khi thương bҵng
0. Sau đó viӃt các sӕ dư theo chiӅu tӯ phép chia cuӕi cùng đӃn phép chia đҫu
tiên.

                                                                                   3
Thí dө:

              (33)10 = (100001)2


                     33   2

                     1    16   2
                          0        8   2
                               0           4    2
                                       0           2       2

                                               0           1   2
                                                       1       0



                    Hình 1.1. Cách đәi mӝt sӕ hӋ mưӡi sang hӋ hai
      Quy tҳc đәi sӕ thұp phân hӋ mưӡi sang hӋ hai: Lҩy sӕ cҫn đәi nhân vӟi 2,
tích gӗm phҫn nguyên và phҫn lҿ. Lҩy phҫn lҿ nhân tiӃp vӟi 2 cho đӃn khi nào
tích thu đưӧc bҵng 1 thì dӯng lҥi. Chӑn riêng phҫn nguyên cӫa các tích thu đưӧc
và viӃt theo thӭ tӵ tӯ phép nhân đҫu tiên đӃn phép nhân cuӕi cùng. Thí dө:

                    (0,125)10 = (0,001)2

                               0,125           x 2 =           0   ,250
                               0,250           x 2 =           0   ,50
                               0,50             x 2 =          1   ,0




                   Hình 1.2. Các đәi mӝt sӕ thұp phân hӋ mưӡi sang hӋ hai
b. ChuyӇn tӯ hӋ nhӏ phân sang hӋ thұp phân:
     ĐӇ chuyӇn tӯ hӋ nhӏ phân sang thұp phân ta tính tәng các tích sӕ giӳa các
hӋ sӕ vӟi các trӑng sӕ 2i tҥi tӯng vӏ trí thӭ i.
     Thí dө:
     (1110,11)2 = 1.23 + 1.22 + 1.21 + 0.20 + 1.2-1 + 1.2-2
     = 8 + 4 + 2 + 0,5 + 0,25 = (14,75)10
1.1.2.2. ChuyӇn đәi giӳa thұp lөc hoһc hӋ bát phân sang hӋ nhӏ phân


                                                                             4
Quy tҳc: Nhóm 4 bit (hoһc 3 bit cho hӋ bát phân) bҳt đҫu tӯ bit ngoài cùng
bên phҧi, tính giá trӏ sӕ hӑc theo quy luұt giá trӏ riêng cho tӯng nhóm. ViӃt các
giá trӏ này liên tiӃp nhau.
      Thí dө:
      Cho sӕ nhӏ phân: 11110101 chuyӇn sang hӋ thұp lөc và hӋ bát phân như sau:
    (11 110 101) 3 6 5 trong hӋ bát phân là sӕ 365
    (1111 0101) 15 5 F5 trong hӋ thұp lөc là sӕ F5
    Khi cҫn chuyӇn ngưӧc lҥi làm tương tӵ. Thí dө:
    (120)8 = (001 010 000) 2
    (120)16 = (0001 0010 0000)2
    1.3. Các phép toán bit
    1.3.1. Phép toán AND
    Kí hiӋu: &
    Ý nghĩa: Nhân logic trên các bit. Phép toán này thӵc hiӋn trên tӯng cһp bit
tương ӭng cӫa các toán hҥng theo quy tҳc trong bҧng sau:
                                  A      B A&B
                                  0      0      0
                                  0      1      0
                                  1      0      0
                                  1      1      1
                        Bҧng 1.3. Bҧng chân lý phép toán AND trên bit
1.1.3. Các phép toán logic
1.1.3.1. Phép toán OR
     Kí hiӋu: |
     Ý nghĩa: Cӝng logic trên các bit. Phép toán này thӵc hiӋn trên tӯng cһp bit
tương ӭng cӫa các toán hҥng theo quy tҳc trong bҧng sau:
                                  A      B    A|B
                                  0      0      0
                                  0      1      1
                                  1      0      1
                                  1      1      1
                    Bҧng 1.4. Bҧng chân lý phép toán OR trên bit
1.1.3.2. Phép toán XOR
     Kí hiӋu: ^




                                                                               5
Ý nghĩa: Phép cӝng logic trên các bit. Thӵc hiӋn trên tӯng cһp bit tương
ӭng cӫa các toán hҥng theo quy tҳc trong bҧng sau.
                               A      B     A^B
                               0      0        0
                               0      1        1
                               1      0        1
                               1      1        0
                    Bҧng 1.5. Bҧng chân lý phép toán XOR trên bit
1.1.3.3. Phép toán NOT
     Kí hiêu: ~
     Ý nghĩa: phép đҧo bit, đәi các giá trӏ trong mӛi bit cӫa toán hҥng x tӯ 0->1,
1->0.
1.1.3.4. Phép toán dӏch trái/phҧi
     - x SHR i: Phép dӏch phҧi, cho giá trӏ có đưӧc tӯ sӕ nguyên x sau khi dӏch
sang phҧi i bit; các sӕ 0 sӁ lҩp đҫy các kӃt quҧ bên trái nӃu là sӕ nguyên dương;
nӃu không phҧi là sӕ nguyên dương thì sӕ 1 sӁ lҩp đҫy các kӃt quҧ bên trái.
     Thí dө:
          5      >> 2 = 1 ( 0101 >> 2 = 0001)
     - x SHL i: Phép dӏch trái, cho giá trӏ có đưӧc tӯ sӕ nguyên x sau khi dӏch
sang trái i bit; các sӕ 0 sӁ lҩp đҫy các kӃt quҧ ӣ bên phҧi.
          5      << 2 = 20

1.2. Vi xӱ lý 8086, tұp lӋnh và các mode đӏa chӍ

1.2.1. Vi xӱ lý 8086
     Vi xӱ lý (VXL) làm nhiӋm vө cӫa bӝ xӱ lý trung tâm CPU nên thưӡng
đươc gӑi là CPU và đưӧc đһt ӣ trung tâm bҧn mҥch chính. VXL đưӧc chӃ tҥo
trên cơ sӣ công nghӋ chӃ tҥo các mҥch vi điӋn tӱ tích hӧp rҩt lӟn vӟi các phҫn tӱ
cơ bҧn là các Transistor.
     Các máy tính IBM tương thích vӟi VXL cӫa hãng Intel nên ta sӁ đi tìm hiӇu
vӅ VXL cӫa intel. Hӑ VXL cӫa Intel 80x86 vӟi x là 1,2,3,4, đӃn sӕ 5 thì đәi
thành Pentium. Ngoài ra còn có các VXL cӫa các hãng khác.
     80x86 là VXL 16 bit, tӭc là nó có bus dӳ liӋu 16 bit. Do vұy nó có khҧ năng
truy xuҩt dӳ liӋu 2 byte mӝt lҫn. bus đӏa chӍ có đӝ rӝng 20 bit. Tӭc là nó có khҧ
năng xác đӏnh đӏa chӍ cӫa 220 ô nhӟ = 1MB đӏa chӍ byte nhӟ vұt lý.




                                                                                6
VӅ mһt cҩu trúc, CPU hay VXL có hai phҫn chӭc năng đӝc lұp đó là BIU
và EU:
     BIU là đơn vӏ ghép nӕi, nó thӵc hiӋn tҩt cҧ các công viӋc vӅ BUS cho EU.
Nó thiӃt lұp khâu nӕi vӟi thӃ giӟi bên ngoài là các Bus đӏa chӍ, sӕ liӋu và điӅu
khiӇn. BIU bao gӗm các thanh ghi đoҥn nhӟ, thanh ghi con trӓ lӋnh và bӝ điӅu
khiӇn logic Bus.
     EU là đơn vӏ thi hành lӋnh, EU gӗm hai khӕi: khӕi tính toán sӕ hӑc và logic
ALU và khӕi điӅu khiӇn CU. EU có trách nhiӋm xӱ lý dӳ liӋu, nó duy trì trҥng
thái cӫa VXL, kiӇm soát các thanh ghi đa năng và toán hҥng lӋnh. EU gӗm các
thanh ghi đa năng, thanh ghi cӡ.
     Khi VXL hoҥt đӝng, dӳ liӋu đưӧc truyӅn giӳa VXL và thiӃt bӏ vào ra khi
có yêu cҫu cӫa EU. Chúng không đưӧc truyӅn trӵc tiӃp tӟi EU mà phҧi qua mӝt
vùng nhӟ RAM có dung lưӧng nhӓ hơn 6 byte gӑi là hàng nhұp lӋnh trưӟc PQ.
Rӗi sau đó mӟi đưӧc truyӅn vào đơn vӏ lӋnh IU. TiӃp đó IU sӁ điӅu khiӇn EU đӇ
cho lӋnh đưӧc thӵc hiӋn bӣi ALU.
     Mӝt chu kì lӋnh cӫa 8086 có thӇ coi đơn giҧn gӗm hai thӡi khoҧng: lҩy lӋnh
tӯ bӝ nhӟ và thӵc hiӋn lӋnh. Khi EU đang thӵc hiӋn lӋnh trưӟc thì BIU đã tìm và
lҩy lӋnh tiӃp theo tӯ bӝ nhӟ, giҧi mã nó và nҥp vào PQ vào, khiӃn cho thӡi gian
lҩy lӋnh cӫa 8086 có thӇ coi là bҵng 0. Sau này chúng ta biӃt đӃn cơ chӃ này
trong các VXL vӅ sau cӫa Intel đó là cơ chӃ đưӡng ӕng.

1.2.2. Các thanh ghi và mode đӏa chӍ trong 8086
     Thanh ghi là mӝt bӝ nhӟ dҥng RAM đưӧc tích hӧp ngay trong VXL. Vì tӕc
đӝ truy cұp các thanh ghi nhanh hơn RAM, nên thanh ghi đưӧc dùng đӇ lưu trӳ
các dӳ liӋu tҥm thӡi cho quá trình xӱ lý và tính toán bên trong máy tính.

1.2.2.1. Cách đӏnh đӏa chӍ byte nhӟ trong 8086
     Bus đӏa chӍ cӫa 8086 có 20 bit, đӏnh đӏa chӍ cho 1 MB bӝ nhӟ, trong khi đó
các thanh ghi trong 8086 đӅu có đӝ rӝng là 16 bit, nên phҧi có cơ chӃ đӇ đánh đӏa
chӍ logic và vұt lý cho không gian nhӟ 1MB. Cách đánh đӏa chӍ như sau:
      Chương trình sӁ chia không gian nhӟ vұt lý thành các đoҥn nhӟ logic, vӟi
kích thưӟc 64Kbyte mӛi đoҥn, các byte trong đoҥn là liên tiӃp nhau. Mӛi đoҥn
nhӟ đưӧc chương trình gҳn cho mӝt đӏa chӍ đoҥn, đó là đӏa chӍ byte nhӟ thҩp
nhҩt trong đoҥn nhӟ. Hai đoҥn nhӟ liӅn kӅ nhau nhҩt thiӃt phҧi cách nhau 16
byte, do đó các đoҥn có đӏa chӍ là bӝi sӕ 16 cӫa nhau. Như vұy chương trình có
thӇ chӭa các đoҥn tách rӡi, phӫ lҩp hoһc chӗng lên nhau. Bên trong đoҥn có đӏa


                                                                               7
chӍ offset đӇ chӍ khoҧng cách tӯ đӏa chӍ thҩp nhҩt trong đoҥn tӟi ô nhӟ đó. Giá trӏ
offset cho phép xác đӏnh chính xác đӏa chӍ logic cӫa byte nhӟ trong đoҥn đó.
      Như vұy, mӝt byte nhӟ đưӧc đӏnh đӏa chӍ logic bӣi mӝt cһp 2 thanh ghi 16
bit là chӭa đӏa chӍ đoҥn và đӏa chӍ đӝ lӋch (segment:offset). Ngưӡi lұp trình chӍ
quan tâm tӟi đӏa chӍ logic nhưng khi truy xuҩt bӝ nhӟ, đơn vӏ ghép nӕi Bus BIU
trong VXL sӁ tính tӯ đó ra đӏa chӍ vұt lý thұt sӵ cӫa byte nhӟ cҫn truy cұp theo
công thӭc:
       Đ͓a ch͑ v̵t lý=đ͓a ch͑ đo̩n ×16 + đ͓a ch͑ đ͡ l͏ch (segment×16 + offset)
     ĐiӅu này đưӧc BIU thӵc hiӋn dӉ dàng bҵng cách dӏch trái giá trӏ thanh ghi
chӭa đӏa chӍ đoҥn đi 4 bit rӗi cӝng vӟi giá trӏ offset trong thanh ghi chӭa đӝ lӋch
(vì khi mӝt sӕ nhӏ phân đưӧc dӏch trái đi 4 digit, tương đương vӟi viӋc nhân nó
vӟi 24 = 16).
     Vì mӛi thanh ghi đoҥn dài 16 bit nên có thӇ đӏnh đӃn 64 k đoҥn nhӟ, và sӕ
đӏa chӍ offset (tương ӭng vӟi kích thưӟc mӛi đoҥn) sӁ là 64 kbyte. Do đó không
gian đӏa chӍ logic sӁ lӟn hơn và bҵng 64 kbyte × 64 kbyte đӏa chӍ = 4 Gbyte nhӟ.

1.2.2.2. Các thanh ghi trong 8086
      8086 có 14 thanh ghi 16 bit.
      Các thanh ghi đa năng AX, BX, CX, DX. Chúng đưӧc dùng đӇ lưu trӳ dӳ
liӋu tҥm thӡi trong khi thӵc hiӋn chương trình. Ưu điӇm cӫa viӋc sӱ dөng thanh
ghi bên trong cho viӋc lưu trӳ tҥm thӡi dӳ liӋu là cho phép VXL có thӇ truy cұp
dӳ liӋu nhanh hơn rҩt nhiӅu so vӟi viӋc phҧi truy cұp bӝ nhӟ ngoài. Các thanh
ghi này đưӧc tách thành hai phҫn, mӛi phҫn 8 bit, phҫn chӭa 8 bit cao là AH,
BH, CH, DH và phҫn chӭa 8 bit thҩp là AL, BL, CL , DL. Mӛi phҫn đӅu có thӇ
đưӧc đӏa chӍ hóa tách biӋt.
     y Thanh ghi AX: Thanh ghi tích lũy (Accumulator Register) ± là thanh ghi
       đóng vai trò trung tâm đӕi vӟi phép nhân và phép chia. Thanh ghi AH
       thưӡng đưӧc sӱ dөng đӇ truy nhұp qua mӝt kênh vào/ra.
     y Thanh ghi BX: Thanh ghi cơ sӣ (Base Register) ± đưӧc dùng cho các
       loҥi đӏnh đӏa chӍ đһc biӋt đӇ tính toán đӏa chӍ, thưӡng đưӧc dùng đӇ chӭa
       con trӓ trӓ tӟi bӝ nhӟ.
     y Thanh ghi CX: Thanh ghi đӃm (Count Register) ± chӭa sӕ đӃm trong các
       lӋnh lһp vòng.
     y Thanh ghi DX: Thanh ghi dӳ liӋu (Data Register) ± là thanh ghi mӣ rӝng
       cӫa thanh ghi AX trong các lӋnh nhân và chia. Thanh ghi này chӭa nӱa
       cao cӫa mӝt tích 32 bit hoһc nӱa cao cӫa mӝt sӕ bӏ chia 32 bit. Trong


                                                                                 8
viӋc thӵc hiӋn các lӋnh đӑc/viӃt các cәng vào/ra, thanh ghi này đưӧc
        dùng đӇ chӭa đӏa chӍ cӫa các cәng cҫn đӑc/viӃt có giá trӏ lӟn hơn FFh.
 Các thanh ghi đoҥn CS, DS, SS, ES: có 4 thanh ghi đoҥn dùng đӇ lưu trӳ đӏa
 chӍ 16 bit cӫa 4 loҥi đoҥn nhӟ logic: đoҥn mã lӋnh CS, đoҥn dӳ liӋu DS, đoҥn
 ngăn xӃp SS, đoҥn phө ES. Ngăn xӃp (stack) là mӝt vùng nhӟ đưӧc đһt ra
 ngoài đӇ lưu trӳ đӏa chӍ và dӳ liӋu trong khi thӵc hiӋn chương trình con.
      y Thanh ghi đoҥn mã lӋnh CS: là thanh ghi chӭa đӏa chӍ đoҥn cӫa vùng
         chӭa mã lӋnh cӫa chương trình đang thӵc hiӋn.
      y Thanh ghi đoҥn dӳ liӋu DS: là thanh ghi đӏa chӭa đӏa chӍ đoҥn cӫa
         vùng dӳ liӋu mà chương trình đang thӵc hiӋn sӱ dөng, vùng này
         thưӡng chӭa các biӃn cӫa chương trình.
      y Thanh ghi đoҥn ngăn xӃp SS: là thanh ghi chӭa đӏa chӍ đoҥn bӝ nhӟ
        ngăn xӃp (stack) cӫa chương trình.
     y Thanh ghi đoҥn phө (mӣ rӝng, bә xung): là thanh ghi chӭa đӏa chӍ
         đoҥn cӫa vùng nhӟ bә xung mà chương trình đang sӱ dөng, vùng này
         cũng thưӡng chӭa các biӃn cӫa chương trình.
   Các thanh ghi con trӓ và chӍ sӕ: gӗm có các thanh ghi: BP, SP, SI, DI, IP.
      y SP (Stack Pointer) ± thanh ghi con trӓ stack: nó luôn kӃt hӧp vӟi SS đӇ
        chӍ ra đӍnh tӭc thӡi cӫa ngăn xӃp. Sau mӛi thao tác cҩt mӝt tӯ (word)
        vào ngăn xӃp SP sӁ tӵ đӝng giҧm đi 2 đơn vӏ, và ngưӧc lҥi sau mӛi
         thao tác lҩy mӝt tӯ ra khӓi ngăn xӃp SP sӁ tӵ đӝng tăng lên 2 đơn vӏ.
      y BP (Base Stack Pointer) ± thanh ghi con trӓ cơ sӣ: là thanh ghi con trӓ
         đӇ đánh dҩu ngăn xӃp, Trong nhiӅu thao tác vӟi stack cҫn sӱ dөng
         thêm thanh ghi này, chҷng hҥn như truyӅn thông sӕ thông qua stack.
     y SI (Source Index) và DI (Destination Index) ± thanh ghi con trӓ chӍ sӕ
        nguӗn và thanh ghi con trӓ chӍ sӕ đích: đưӧc thiӃt kӃ đӇ chuyên sӱ
        dөng trong các thao tác vұn chuyӇn dӳ liӋu. Trong mӝt sӕ lӋnh cӫa
        8086 các thanh ghi này luôn đưӧc kӃt hӧp vӟi các thanh ghi đoҥn DS,
        ES đӇ trӓ tӟi nguӗn và đích cӫa thao tác vұn chuyӇn dӳ liӋu. Đó là cҳp
        DS: SI và ES:DI.
    Thanh ghi con trӓ lӋnh IP (Intruction Pointer): Thanh ghi con trӓ lӋnh
luôn chӭa đӏa chӍ lӋch cӫa lӋnh tiӃp theo sӁ đưӧc thi hành trong đoҥn nhӟ CS.
Sau khi mӝt lӋnh đưӧc thi hành thì IP lҥi đưӧc bӝ VXL thay đәi giá trӏ đӇ trӓ tӟi
lӋnh tiӃp theo sӁ đưӧc thi hành.




                                                                                 9
Thanh ghi cӡ Flag (Flags Register): đây là thanh ghi 16 bit, trong đó mӛi
bit đưӧc sӱ dөng đӇ thӇ hiӋn mӝt trҥng thái cӫa bӝ VXL tҥi mӝt thӡi điӇm nhҩt
đӏnh trong quá trình thӵc hiӋn chương trình, trong VXL 8086 mӟi chӍ có 9 bit
đưӧc sӱ dөng, ngưӡi ta gӑi mӛi bit đó là mӝt cӡ, mӛi cӡ thưӡng đưӧc biӇu diӉn
bҵng mӝt kí hiӋu gӧi nhӟ, mӛi cӡ đӅu có hai trҥng thái khác nhau là 0 và 1.
Ngưӡi lұp trình ASM hay dùng trҥng thái các bit cӡ làm điӅu kiӋn cho các lӋnh
nhҧy có điӅu kiӋn.
               x   x x x O D I T S Z x A x P x                  C


    x: không đưӧc đӏnh nghĩa.
      y C hoһc CT (Carry flag): cӡ nhӟ. CF = 1 khi sӕ nhӟ tràn khӓi bit có
        trӑng sӕ lӟn nhҩt.
      y P hoһc PF (Parity flag): cӡ parity. PF phҧn ánh tính chҹn lҿ (parity)
        cӫa tәng sӕ bit có trong kӃt quҧ. PF = 1 khi tәng sӕ bit 1 trong kӃt quҧ
        là chҹn.
      y A hoһc AF (Auxiliary carry flag): cӡ nhӟ phө, rҩt có ý nghĩa khi ta làm
        viӋc vӟi các sӕ BCD. AF = 1 khi có nhӟ hoһc mưӧn tӯ mӝt sӕ BCD
        thҩp (4 bit thҩp) sang mӝt sӕ BCD cao (4 bit cao).
      y Z hoһc ZF ( Zero flag): cӡ rӛng, ZF = 1 khi kӃt quҧ bҵng 0.
      y S hoһc SF (Sign flag): cӡ dҩu, SF = 1 khi kӃt quҧ âm.
      y hoһc OF (Overflow flag): cӡ tràn, OF = 1 khi có hiӋn tưӧng tràn sӕ
        hӑc, đó là trưӡng hӧp sӕ quá lӟn vưӧt ra khӓi dung lưӧng nơi gӱi đӃn.
      y T hoһc TF (Trap flag): cӡ bүy, TF = 1 thì CPU làm viӋc ӣ chӃ đӝ chҥy
        tӯng lӋnh( chӃ đӝ này cҫn dùng khi cҫn tìm lӛi trong mӝt chương
        trình).
      y I hoһc IF (Interrupt enable flag): cӡ cho phép ngҳt, IF = 1 thì CPU cho
        phép các yêu cҫu ngҳt đưӧc tác đӝng.
      y D hoһc DF (Direction flag): cӡ hưӟng, DF = 1 khi CPU làm viӋc vӟi
        chuӛi kí tӵ theo thӭ tӵ tӯ trái sang phҧi (hay còn gӑi D là cӡ lùi).

1.2.3. Các mode đӏa chӍ cӫa 8086
      Hay còn gӑi là các chӃ đӝ đӏa chӍ, các phương pháp xác đӏnh đӏa chӍ cӫa
các toán hҥng có trong lӋnh. Lưu ý rҵng tұp các thanh ghi cӫa bӝ xӱ lý đưӧc sҳp
xӃp cũng tҥo nên mӝt bӝ nhӟ tӕc đӝ cao và cũng có mӝt không gian đӏa chӍ.




                                                                             10
Đӏa chӍ hiӋu dөng EA ~ offset hay đӝ lӋch cӫa ô nhӟ chӭa toán hҥng mong
muӕn tính tӯ đӏa chӍ cơ sӣ đoҥn. Đӏa chӍ vұt lý cӫa ô nhӟ chӭa toán hҥng đưӧc
8086 xác đӏnh bҵng cách cӝng đӏa chӍ hiӋu dөng vӟi đӏa chӍ cơ sӣ đoҥn nҵm
trong các thanh ghi đoҥn. Thanh ghi đoҥn thông dөng nhҩt là thanh ghi DS.
      8086 có các mode đӏa chӍ sau:
      y Đӏnh đӏa chӍ tӭc thӡi: các đơn giҧn nhҩt đӇ xác đӏnh mӝt toán hҥng là
        phҫn đӏa chӍ cӫa lӋnh chӭa chính toán hҥng đó chӭ không cҫn đӏa chӍ
         hoһc thông tin khác mô tҧ toán hҥng đó ӣ đâu. Mӝt toán hҥng như vұy
         gӑi là toán hҥng tӭc thӡi bӣi vì toán hҥng đưӧc tìm và nҥp tӵ đӝng tӯ
         bӝ nhӟ cùng lúc vӟi lӋnh và đưӧc sӱ dөng ngay lұp tӭc. Đӏnh đӏa chӍ
         tӭc thӡi có ưu điӇm là không cҫn mӝt truy xuҩt bӝ nhӟ nào. Tuy nhiên
         nó có nhưӧc điӇm là toán hҥng bӏ giӟi hҥn bӣi mӝt sӕ chӍ đһt vӯa trong
         trưӡng đӏa chӍ.
         Thí dө: MOV CX, 437Bh
      y Đӏnh đӏa chӍ trӵc tiӃp: phương pháp này xác đӏnh mӝt toán hҥng bҵng
        cách cung cҩp đӏa chӍ cӫa tӯ nhӟ chӭa toán hҥng cho bӝ xӱ lý. Vӟi chӃ
         đӝ đӏnh đӏa chӍ bӝ nhӟ đơn giҧn nhҩt, đӏa chӍ hiӋu dөng chӍ là sӕ 16 bit
         đưӧc viӃt tiӃp trong câu lӋnh.
         Thí dө: MOV BL, [437Ah], nҥp nӝi dung ô nhӟ có đӝ lӋch tính tӯ đӏa
         chӍ cơ sӣ đoҥn là 437A vào thanh ghi BL. Khi đó VXL sӁ tính toán
         đӏa chӍ cӫa ô nhӟ bҵng cách cӝng thêm đӏa chӍ hiӋu dөng 437A vào đӏa
         chӍ cơ sӣ đoҥn dӳ liӋu.
         ChӃ đӝ đӏnh đӏa chӍ này đưӧc gӑi là trӵc tiӃp vì đӝ dӏch chuyӇn cӫa
         toán hҥng đưӧc chӍ ra trӵc tiӃp trong câu lӋnh.
         Thí dө khác: MOV BX, [437Ah], copy mӝt tӯ 16 bit tӯ ô nhӟ vào
         thanh ghi BX. Bӣi mӛi đӏa chӍ trong 8086 đҥi diӋn cho 1 byte, do đó
         nӝi dung cӫa ô nhӟ có đӏa chӍ lӋch so vӟi đӏa chӍ đoҥn dӳ liӋu DS là
         437A sӁ đưӧc copy vào thanh ghi BL, nӝi dung ô nhӟ có đӏa chӍ lӋch
         437B sӁ đưӧc copy vào thanh ghi BH.
         Ngoài ra đӏnh đӏa chӍ trӵc tiӃp còn đưӧc dùng đӇ xác đӏnh toán hҥng
         đích trong bӝ nhӟ, ví dө: MOV [437Ah], BX sӁ copy vào ô nhӟ có đӏa
         chӍ lӋch 437A nӝi dung thanh ghi BL, và copy nӝi dung thanh ghi BH
         vào ô nhӟ có đӏa chӍ lӋch là 437B.
      y Đӏnh đӏa chӍ thanh ghi: Trong chӃ đӝ này, thanh ghi sӁ là toán hҥng
        nguӗn cӫa câu lӋnh. Thí dө: MOV CX, AX. Trong đó, toán hҥng
        nguӗn là toán hҥng đӭng sau dҩu phҭy, toán hҥng đích là toán hҥng

                                                                              11
đӭng trưӟc dҩu phҭy, lӋnh MOV CX, AX sӁ copy nӝi dung thanh ghi
   AX vào thanh ghi CX. Ta có thӇ copy nӝi dung bҩt cӭ thanh ghi 16 bit
   nào sang thanh ghi 16 bit khác, cũng có thӇ copy nӝi dung bҩt cӭ thanh
   ghi 8 bit nào sang thanh ghi 8 bit khác, các trưӡng hӧp còn lҥi là không
   thӇ.
y Đӏnh đӏa chӍ gián tiӃp: trong chӃ đӝ này, trưӡng đӏa chӍ cho biӃt tӯ
  nhӟ nào hoһc thanh ghi nào chӭa đӏa chӍ cӫa toán hҥng. Trong nhóm
   này có các loҥi như sau:
   - Đӏnh vӏ gián tiӃp thanh ghi: lúc này đӏa chӍ hiӋu dөng nҵm ӣ mӝt
   trong các thanh ghi BX, BP, SI hoһc DI.
   Thí dө: MOV AX, [SI] ; chuyӇn nӝi dung cӫa ô nhӟ trong đoҥn hiӋn
   tҥi có offset là nӝi dung cӫa thanh ghi SI và thanh ghi AX.
   - Đӏnh vӏ cơ sӣ: EA là tәng cӫa đӝ dӏch chuyӇn và nӝi dung cӫa thanh
   ghi BX hoһc BP.
   -Thí dө: MOV [BX] + displacement, AL; chuyӇn nӝi dung cӫa thanh
   ghi AL vào ô nhӟ có đӏa chӍ offset bҵng tәng nӝi dung cӫa BX vӟi đӝ
   dӏch chuyӇn.
 y Đӏnh vӏ chӍ sӕ (indexed addressing): EA là tәng cӫa đӝ dӏch chuyӇn
    và nӝi dung cӫa thanh ghi SL hoһc DI.
   Lý do có chӃ đӝ này như sau. NhiӅu thuұt toàn cҫn thӵc hiӋn mӝt thao
  tác nào đó trên mӝt chuӛi cҩu trúc dӳ liӋu lưu giӳ trong nhӳng vӏ trí
  nhӟ liên tiӃp. Thí dө xét mӝt khӕi gӗm n tӯ lӋnh máy chiӃm các vӏ trí
  A, A + 1, A + 2, «, A + n-1. Các tӯ này cҫn đưӧc di chuyӇn đӃn các
   vӏ trí B, B + 1, B + 2, « ,B + n-1. Trong trưӡng hӧp này có thӇ thӵc
   hiӋn lӋnh MOV A, B rӗi thay đәi chính lӋnh đó thành MOVE A + 1, B
   + 1 và lһp lҥi cho tӟi khi cҧ n tӯ đưӧc sao chép hӃt. Bҵng cách đӏnh đӏa
   chӍ gián tiӃp có thӇ thӵc hiӋn đưӧc điӅu này. Mӝt thanh ghi hoһc tӯ
   nhӟ đưӧc nҥp đӏa chӍ A, mӝt thanh ghi hoһc tӯ nhӟ khác đưӧc nҥp đӏa
   chӍ B. LӋnh MOV dùng 2 thanh ghi này làm các con trӓ và sau mӛi lҫn
   sao chép mӝt tӯ con trӓ đưӧc tăng lên 1. Các con trӓ là mӝt phҫn cӫa
   dӳ liӋu chӭ không phҧi là phҫn cӫa chương trình và nhӳng ngưӡi sӱ
   dөng không đưӧc dùng chung đӗng thӡi. Mӝt giҧi pháp khác là có mӝt
   sӕ thanh ghi gӑi là thanh ghi ch͑ s͙ hoҥt đӝng như sau. Đӏa chӍ có 2
   phҫn: sӕ cӫa mӝt thanh ghi chӍ sӕ và mӝt hҵng sӕ. Đӏa chӍ cӫa toán
   hҥng là tәng cӫa hҵng sӕ vӟi nӝi dung cӫa thanh ghi chӍ sӕ. Trong thí
   dө này, nӃu cҧ hai đӏa chӍ đưӧc đӏnh chӍ sӕ bҵng cách dùng mӝt thanh

                                                                        12
ghi chӍ sӕ chӭa sӕ nguyên k, lӋnh MOV A, B sӁ chuyӇn nӝi dung vө trí
   nhӟ A + k tӟi B + k. Bҵng cách khӣi đӝng thanh ghi chӍ sӕ là 0 và tăng
   nӝi dung thanh ghi này lên mӝt lưӧng bҵng kích thích cӫa tӯ sau khi
   sao chép mӝt tӯ, chӍ cҫn mӝt thanh ghi cho vòng lһp sao chép. Hơn
   nӳa viӋc tăng thanh ghi sӁ nhanh hơn viӋc tăng mӝt vӏ trí nhӟ. ViӋc
   đánh chӍ sӕ đưӧc sӱ dөng rӝng rãi đӇ đӏnh đӏa chӍ mӝt trưӡng tҥi mӝt
   khoҧng cách đã biӃt tính tӯ điӇm đҫu cӫa mӝt cҩu trúc dӳ liӋu đã cho.
   Các biӃn cөc bӝ trong mӝt thӫ tөc đưӧc truy cұp theo cách này.
     ViӋc tăng hoһc giҧm giá trӏ thanh ghi chӍ sӕ trưӟc hoһc sau khi nó
   đưӧc sӱ dөng là viӋc làm thưӡng xuyên xҧy ra. Vì vұy ngưӡi ta thưӡng
   đưa các lӋnh đӏnh đӏa chӍ đһc biӋt hoһc thұm chí có nhӳng thanh ghi
   chӍ sӕ đһc biӋt mà tӵ chúng có thӇ tăng hoһc giҧm giá trӏ. ViӋc sӱa đәi
   tӵ đӝng mӝt thanh ghi chӍ sӕ đưӧc gӑi là đánh ch͑ s͙ t͹ đ͡ng
   (autoindexing).
   Thí dө lӋnh:        MOV AL, [SI] + displacement; chuyӇn nӝi dung ô
   nhӟ có đӏa chӍ offset bҵng tәng cӫa nӝi dung SI vӟi đӝ dӏch chuyӇn
   vào thanh ghi AL.
                         MOV AH,[BX] [SI] + displacement; chuyӇn
   nӝi dung cӫa ô nhӟ có đӏa chӍ offset bҵng tәng cӫa đӝ dӏch chuyӇn vӟi
   nӝi dung cӫa BX và SI vào thanh ghi AH.
    Đây là kiӇu đ͓nh đ͓a ch͑ ch͑ s͙ và cơ sͧ, EA là tәng cӫa nӝi dung
   thanh ghi cơ sӣ, thanh ghi chӍ sӕ và đӝ dӏch chuyӇn.
y Đӏnh đӏa chӍ ngăn xӃp (stack addressing): Ngăn xӃp gӗm các phҫn tӱ
  dӳ liӋu (tӯ, kí tӵ, bit v.v«) đưӧc lưu trӳ theo mӝt trұt tӵ liên tiӃp trong
  bӝ nhӟ. Phҫn tӱ đҫu tiên đưӧc cҩt vào ngăn xӃp sӁ ӣ đáy ngăn xӃp.
  Phҫn tӱ mӟi nhҩt đưӧc cҩt vào sӁ ӣ đӍnh ngăn xӃp. KӃt hӧp vӟi mӛi
  ngăn xӃp là mӝt thanh ghi hoһc tӯ nhӟ chӭa đӏa chӍ cӫa đӍnh ngăn xӃp
  đưӧc gӑi là con tr͗ ngăn x͇p (stack pointer).
   Máy tính có lӋnh PUSH cҩt các nӝi dung cӫa ô nhӟ hoһc thanh ghi vào
   ngăn xӃp. LӋnh này phҧi thӵc hiӋn viӋc sao chép phҫn tӱ đó và tăng
   con trӓ ngăn xӃp. Ngưӧc lҥi, lӋnh POP lҩy nӝi dung đӍnh ngăn xӃp đưa
   trӣ lҥi thanh ghi hoһc ô nhӟ phҧi thӵc hiӋn sao chép mӟi vào nơi thích
   hӧp và giҧm con trӓ ngăn xӃp.
     Thí dө lӋnh: PUSH AX        ;cҩt nӝi dung cӫa thanh ghi AX vào ngăn
   xӃp



                                                                          13
POP AX     ;hӗi phөc giá trӏ thanh ghi AX tӯ nӝi dung
            đӍnh ngăn xӃp.
              Mӝt sӕ lӋnh không đӏa chӍ cũng có thӇ đưӧc sӱ dөng cùng vӟi ngăn
            xӃp. Đӏnh dҥng lӋnh này chӍ ra rҵng 2 toán hҥng đưӧc lҩy ra khӓi ngăn
            xӃp, toán hҥng này tiӃp sau toán hҥng kia, phép toán đưӧc thӵc hiӋn
            (thí dө nhân hoһc AND) và kӃt quҧ đưӧc cҩt trӣ lҥi ngăn xӃp.

1.3. Ngҳt
       Ngҳt (interrupt) là khҧ năng dӯng chương trình chính đang chҥy đӇ thӵc
hiӋn mӝt chương trình khác rӗi sau đó lҥi quay vӅ thӵc hiӋn tiӃp chương trình
chính.
       Mӝt trong nhӳng tình huӕng xҧy ra ngҳt như sau: trong khi vi xӱ lý đang
thӵc hiӋn chuӛi lӋnh cӫa chương trình chính nӃu mӝt thiӃt bӏ ngoҥi vi nào đó cҫn
trao đәi thông tin vơi vi xӱ lý, nó sӁ gӱi mӝt tín hiӋu yêu cҫu gӑi là yêu c̯u ng̷t
(thí dө INTR) tӟi vi xӱ lý. Vi xӱ lý sӁ thӵc hiӋn nӕt lӋnh hiӋn tҥi và trҧ lӡi bҵng
tín hiӋu ch̭p nh̵n ng̷t (thí dө INTA). Chương trình chính lúc này sӁ bӏ dӯng lҥi
(ngҳt) và vi xӱ lý cҩt giӳ nӝi dung cӫa các thanh ghi đang dùng bҵng lӋnh PUSH
vào mӝt vùng nhӟ đһc biӋt (gӑi là ngăn xӃp) rӗi chuyӇn sang chương trình con
phͭc vͭ ng̷t tӭc là chương trình trao đәi thông tin mà đơn vӏ yêu cҫu.
       Sau khi xong viӋc, nhӡ lӋnh RET và các lӋnh POP hӗi phөc ngăn xӃp, vi
xӱ lý sӁ quay vӅ đúng chӛ bӏ ngҳt và tiӃp tөc thӵc hiӋn chương trình chính như
hình 2.10 chӍ ra.
       Các ngҳt không chӍ có ý nghĩa quan trӑng đӕi vӟi phҫn mӅm mà cҧ vӟi
phҫn cӭng. Các ngҳt trong hӑ vi xӱ lý 80x86 có thӇ đưӧc phát ra tӯ mӝt trong ba
nguӗn sau:
     Ng̷t cͱng: do tín hiӋu đưӧc sinh ra bӣi các chip điӋn tӱ hoһc thiӃt bӏ ngoҥi
vi bên ngoài vi xӱ lí gây nên. Đó là mӝt cơ cҩu đơn giҧn và hiӋu quҧ cho phép vi
xӱ lý phҧn ӭng mӝt cách kӏp thӡi vӟi các yêu cҫu ngҳt. Thí dө, ҩn hay nhҧ bàn
phím sӁ gây nên ngҳt cӭng sӕ 9 (ngҳt bàn phím), chương trình xӱ lí ngҳt sӁ phҧn
ӭng bҵng cách đưa kí tӵ đưӧc ҩn vào vùng đӋm cӫa bàn phím, vào vӏ trí ngay sau
kí tӵ đưӧc ҩn lҫn trưӟc.
            Ng̷t có th͋ b͓ che (maskable) do tín hiӋu yêu cҫu ngҳt đưӧc đưa tӟi
chân INTR cӫa vi xӱ lý. Ngҳt này sӁ bӏ vô hiӋu hóa (bӏ che) bҵng lӋnh hӧp ngӳ
CLI (xóa cӡ ngҳt). NӃu bӏ che thì mһc dù đưӧc gӑi, chương trình xӱ lí ngҳt
tương ӭng cũng không đưӧc thӵc hiӋn. LӋnh STI (đһt cӡ ngҳt) cho phép các ngҳt
bӏ che trӣ lҥi hoҥt đӝng.


                                                                                14
Ng̷t không th͋ b͓ che (non-maskable) do tín hiӋu yêu cҫu ngҳt đưӧc
đưa tӟi chân NMI cӫa vi xӱ lý. Ngҳt luôn đưӧc thӵc hiӋn kӇ cҧ khi đưӧc gӑi
ngay sau lӋnh CLI. Ngҳt này liên quan tӟi các hӓng hóc phҫn cӭng nghiêm trӑng
(thí dө, hӓng RAM).
      Ng̷t m͉m: vӟi nguӗn gây ngҳt là các câu lӋnh gӑi ngҳt INT đưӧc sӱ dөng
cùng sӕ thӭ tӵ ngҳt. Thí dө, lӋnh gӑi ngҳt sӕ 5 (in trang màn hình) đưӧc viӃt là
INT 5. Các ngҳt mӅm cho phép gӑi các chương trình phө cӫa hӋ điӅu hành. Ngҳt
mӅm còn có thӇ đưӧc gӑi tӯ ngôn ngӳ bұc cao, lúc đó nó sӁ đưӧc dӏch ra thành
lӋnh hӧp ngӳ INT.
     Ngo̩i l͏: là nguӗn ngҳt thӭ 3 do các lӛi phát sinh trong quá trình thӵc hiӋn
câu lӋnh (thí dө, ngҳt chia cho mӝt sӕ cho 0), vi xӱ lý sӁ tӵ đӝng ngҳt chương
trình đang chҥy bҵng ngҳt sӕ 0.
     Vào cuӕi mӛi chu trình lӋnh, 8086 sӁ kiӇm tra xem có ngҳt nào đưӧc yêu
cҫu không. NӃu có yêu cҫu ngҳt, 8086 sӁ phҧn ӭng theo các bưӟc sau:
     Giҧm con trӓ ngăn xӃp đi 2 và cҩt thanh ghi cӡ vào ngăn xӃp.
     Không cho phép ngҳt cӭng tӯ chân INTR bҵng cách xóa cӡ ngҳt IF trong
thanh ghi cӡ.
     Xóa cӡ bưӟc TF trong thanh ghi cӡ.
     Giҧm con trӓ ngăn xӃp đi 2 và cҩt nӝi dung thanh ghi đoҥn mã vào ngăn
xӃp.
     Giҧm con trӓ ngăn xӃp đi 2 mӝt lҫn nӳa và cҩt nӝi dung thanh ghi con trӓ
lӋnh hiӋn thӡi vào ngăn xӃp.
     Thӵc hiӋn mӝt lӋnh nhҧy gián tiӃp far jump tӟi phҫn đҫu cӫa chương trình
con phөc vө ngҳt do ngưӡi dùng viӃt.
     Vi xӱ lý 8086 có thӇ phөc vө đưӧc tӟi 256 ngҳt khác ngau, đưӧc đánh sӕ tӯ
0 đӃn 255. Mӛi ngҳt ӭng vӟi mӝt chương trình con phөc vө ngҳt và sӁ đưӧc thӵc
hiӋn khi đưӧc gӑi lҥi. Đӏa chӍ lôgic ô nhӟ bҳt đҫu cӫa mӛi chương trình này gӑi
là mӝt véctơ ng̷t dài 4 byte gӗm đӏa chӍ đoҥn và đӏa chӍ offset 16 bit, đӏa chӍ
offset đưӧc đһt trưӟc đӏa chӍ đoҥn. 256 đӏa chӍ này đưӧc lưu trӳ lҫn lưӧt trong
vùng nhӟ thҩp nhҩt cӫa bӝ nhӟ gӑi là b̫ng các vectơ ng̷t có đӝ dài là 4 x 256 =
1024 byte tӯ đӏa chӍ 0000: 0000 đӃn 0000: 03FF. Như vұy, đӏa chӍ cӫa chương
trình xӱ lí ngҳt sӕ 0 nҵm ӣ 4 ô nhӟ tӯ 0000: 0000 đӃn 0000: 0003, đӏa chӍ cӫa
chương trình ngҳt sӕ 1 tӯ 0000: 0004 đӃn 0000: 0007 v.v« Dó đó đӇ xác đӏnh ô nhӟ
chӭa đӏa chӍ bҳt đҫu cӫa chương trình con phөc vө ngҳt ta chӍ viӋc nhân sӕ ngҳt vӟi 4.




                                                                                   15
1.4. Giӟi thiӋu vӅ hӧp ngӳ

1.4.1. Lұp trình bҵng hӧp ngӳ
     ViӋc lұp trình bҵng ngôn ngӳ máy đòi hӓi ta phҧi nhӟ các mã lӋnh bҵng sӕ
(dưӟi dҥng nhӏ phân), còn đưӧc gӑi là mã máy, phҧi sҳp đһt vӏ trí cӫa mã lӋnh và
các sӕ liӋu trong bӝ nhӟ cӫa máy tính, ngay cҧ sӕ liӋu cũng phҧi viӃt dưӟi dҥng
sӕ. Công viӋc này rҩt nһng nhӑc, tӕn công, dӉ nhҫm lүn và khó chӍnh sӱa.
    Tuy nhiên viӋc viӃt chương trình bҵng ngôn ngӳ máy cũng có nhӳng ưu
điӇm cӫa nó như phát huy tӕi đa đưӧc khҧ năng cӫa tұp lӋnh cӫa bӝ vi xӱ lý,
cũng như sӱ dөng có hiӋu quҧ nhҩt bӝ nhӟ cӫa máy tính, tӕc đӝ thӵc hiӋn
chương trình là nhanh nhҩt và chương trình có kích thưӟc nhӓ nhҩt.
    ĐӇ tránh các khó khăn cӫa viӋc viӃt chương trình bҵng ngô ngӳ máy nhưng
vүn đҥt đưӧc ưu điӇm cӫa viӋc lұp trình bҵng ngôn ngӳ máy ngưӡi ta sӱ dөng
hӧp ngӳ. Hӧp ngӳ là mӝt ngôn ngӳ lұp trình gӧi nhӟ, nó có các ưu nhưӧc điӇm
như sau:
      y Ưu điӇm :
      Vì ngôn ngӳ Assembler rҩt gҫn gũi vӟi ngôn ngӳ máy nên chương trình
      + Chҥy nhanh.
      + TiӃt kiӋm bӝ nhӟ.
      + Có thӇ lұp trình truy cұp qua các giao diӋn vào ra nhưng hiӋn nay các
ngôn ngӳ bұc cao cũng có thӇ làm đưӧc.
      y Nhưӧc điӇm
       + Khó viӃt bӣi vì yêu cҫu ngưӡi lұp trình rҩt am hiӇu vӅ phҫn cӭng.
       + Khó tìm sai: bao gӗm sai vӅ cú pháp (syntax) và sai vӅ thuұt toán
(Algorithm). Chương trình dӏch sӁ thông báo sai ta sӁ dùng debug cӫa DOS đӇ
kiӇm tra.
       + Không chuyӇn chương trình Assembler cho các máy tính có cҩu trúc
khác nhau.
      y Ӭng dөng
      + ViӃt lõi cӫa hӋ điӅu hành.
      + Các chương trình trò chơi ( ngày trưӟc).
      + Tҥo virus.
      + Các chương trình đo và điӅu khiӇn sӱ dөng trong công nghiӋp, ngày nay
các vi điӅu khiӇn đưӧc sӱ dөng mӝt cách rӝng rãi.
     1.4.2. HӋ lӋnh Assembler
     a) HӋ lӋnh assembler gӗm có:


                                                                             16
y Tұp lӋnh MNEMONIC sinh mã máy đӇ chҥy chương trình.
       y Các DIRECTIVE điӅu khiӇn khi dӏch chương trình.
       b) Cú pháp cӫa mӝt dòng lӋnh ASM
       y Mӛi mӝt dòng chӍ đưӧc viӃt mӝt lӋnh.
       y [Label] [Directive/Mnemonic] [Operands] [;Commnet]
           [Nhãn] [Loҥi lӋnh]            [Toán hҥng][Ghi chú]
       Tӯ ; cho đӃn hӃt dòng là ghi chú và nó có hiӋu lӵc chӍ trên 1 dòng.
       ví dө:
       L1:
       mov ax,bx
       c) Tұp lӋnh Mnemonic
       - Tұp lӋnh Mnemonic là gì? Đó là lӋnh cӫa ASM đưӧc thӇ hiӋn bҵng viӃt tҳt
cӫa tiӃng Anh cho dӉ hiӇu.
     Ví dө:
                 TiӃng Anh                           LӋnh dҥng Mnemonic
                    Move                                     mov
                  Addition                                   add
               Multiplication                                mul
    Các quy ưӟc vӅ toán hҥng:
    y SRC: Toán hҥng nguӗn.
    y DST: Toán hҥng đích.
    y REG(reg8/reg16): Toán hҥng là thanh ghi
    y Data: Toán hҥng là hҵng sӕ.
    y Mem: Toán hҥng là biӃn nhӟ.
    y Segreg: Toán hҥng là thanh ghi segment.
   Tұp lӋnh MNEMONIC gӗm có 6 nhóm:
   y Nhóm 1: Các lӋnh di chuyӇn dӳ liӋu
   y Nhóm 2: Các lӋnh sӕ hӑc.
   y Nhóm 3: Các lӋnh thao tác bit
   y Nhóm 4: Các lӋnh thao tác xâu ký tӵ.
   y Nhóm 5: Các lӋnh rӁ nhánh
   y Nhóm 6: Các hӋ thӕng cӡ

1.4.2. Các bưӟc viӃt chương trình hӧp ngӳ
    HiӋn nay có hai chương trình dӏch rҩt phә biӃn là MASM (cӫa hãng
Microsoft) và TASM (cӫa hãng Borland) vӅ cơ bҧn là hai chương dӏch này rҩt
giӕng nhau nhưng khác nhau ӣ chӛ: khi viӃt lӋnh push
    NӃu viӃt :
       push ax


                                                                             17
push bx
     push cx
     thì cҧ hai chương trình đӅu biên dӏch đưӧc. ( cách viӃt này theo MASM).
     Còn trong TASM thì cho phép viӃt
     push ax bx cx

1.4.2.1. Cài đһt chương trình dӏch TASM:
     y Cách 1:
    Mua đĩa bҧn quyӅn nӃu là đĩa mӅm thì có 5 đĩa hoһc là 1 đĩa CD. Hoһc
download phҫn mӅm TASM hoһc MASM vӅ.
     Run cmd
     A: install




       y Cách 2:
     + Tҥo thư mөc: C:TASM
     + Copy 4 tӋp lõi tӯ máy khác đã cài đһt theo cách 1 vӅ thư mөc đã tҥo
trưӟc.

1.4.2.2. Các bưӟc thӵc hiӋn mӝt chương trình Assember trên máy PC :
     (soҥn thҧo chương trình, dӏch chương trình, liên kӃt, chҥy thӱ và
     cách tìm sai bҵng DEBUG cӫa DOS và TD (Turbo Debug) cӫa Borland)
     Bao gӗm 4 bưӟc:
     + Bưӟc 1: Dùng chương trình soҥn thҧo bҩt kì (Edit, NC, TC, «.) đӇ soҥn
thҧo chương trình. Sau khi soҥn thҧo xong phҧi cҩt tӋp có đuôi là .ASM.
     + Bưӟc 2: Dӏch chương trình gӕc có đuôi .ASM thành tӋp có đuôi là .OBJ
     Cú pháp: C:BT> tasm ten tep[.ASM]
     ten tep.OBJ


                                                                               18
Chú ý: khi chương trình dӏch có lӛi thì không sinh ra tӋp có đuôi là .OBJ
    Cách khai báo sai
    ** Error**ten tep.asm[10] Illegal Instruction
    dòng thӭ bao nhiêu lӛi gì
    + Bưӟc 3: Liên kӃt đӇ chuyӇn tên tӋp có đuôi .OBJ sang tӋp .EXE hay
.COM
   Cú pháp: C:BT> tlink ten tep[.OBJ]
   ten tep.EXE hay ten tep.COM
   + Bưӟc 4: Chҥy thӱ chương trình
   Khi chҥy nӃu có lӛi thì dùng debug đӇ kiӇm tra.
   Ví dө:
   .model small
    .stack
    .data
    message db "Hello$"
    .code
    main proc
       mov ax,seg message
       mov ds,ax
        mov ah,09
        lea dx,message
        int 21h
        mov ax,4ch
        int 21h
     main endp
     end main
1.4.3. Cҩu trúc mӝt chương trình hӧp ngӳ dҥng segment đơn giҧn
     Cҩu trúc cӫa mӝt chương trình hӧp ngӳ có liên quan chһt chӁ vӟi cҩu trúc
phҫn cӭng cӫa bӝ vi xӱ lý. Ngưӡi ta đã tҥo dӵng bӕn đoҥn (segment) đưӧc dӵ
tính cho bӝ vi xӱ lý trong quá trình lұp trình: đoҥn mã lӋnh, đoҥn dӳ liӋu, đoҥn
ngăn xӃp và đoҥn mӣ rӝng. Trong đó, ít nhҩt mӝt chương trình hӧp ngӳ phҧi có
mӝt đoҥn mã lӋnh.
     Do chương trình hӧp ngӳ có cҩu trúc như vұy mà ta có khái niӋm vӅ
chương trình hͫp ngͷ d̩ng segment. Mӝt chương trình segment dҥng chuҭn phҧi
đӏnh nghĩa đҫy đӫ bӕn đoҥn, mӛi đoҥn đưӧc bҳt đҫu bҵng chӍ dүn hưӟng



                                                                             19
(directive) segment và kӃt thúc bҵng chӍ dүn hưӟng ENDS, mӛi đoҥn đӅu đưӧc
ngưӡi lұp trình cho trưӟc mӝt tên đӝc lұp vӟi kiӇu cӫa nó.
     Ӣ cuӕi mӛi chương trình hӧp ngӳ có chӍ dүn hưӟng END đӇ hưӟng dүn cho
bӝ dӏch hӧp ngӳ biӃt rҵng chương trình đã kӃt thúc.
     Tuy nhiên, viӋc viӃt mӝt chương trình hӧp ngӳ dҥng segment chuҭn quá
phӭc tҥp, nên chúng ta thưӡng dùng dҥng giҧn lưӧc cӫa nó hay chương trình hͫp
ngͷ d̩ng segment đơn gi̫n.
1.4.3.1. Dҥng thưӡng thҩy 1 chương trình ASM đơn giҧn
     (Khai báo theo directive điӅu khiӇn segment dҥng đơn giҧn)
     .MODEL
     .STACK
     .DATA
          Khai báo biӃn
     .CODE
     Nhãn chương trình:
        Thân chương trình
     END Nhãn chương trình
     Mӝt chương trình asm đưӧc biên dӏch thành công sӁ trӣ thành mӝt file chҥy
có phҫn mӣ rӝng là .com hoһc .exe. Sӵ khác nhau cӫa chương trình dҥng .com và
chương trình dҥng .exe là:
      y Chương trình dҥng .com có tҩt cҧ các phҫn mã lӋnh, dӳ liӋu và ngăn
        xӃp đӅu cùng nҵm trong mӝt segment
      y Chương trình dҥng .exe có phҫn mã lӋnh, dӳ liӋu và ngăn xӃp nҵm trên
        các segment khác nhau.
a) Cҩu trúc chương trình dҥng .Com
    Cҩu trúc:
    .MODEL SMALL
    .CODE org 0100h
    Nhãn chương trình:
       [JMP nhãn khác
            khai báo biӃn
       nhãn khác:]
       Thân chương trình
        int 20h
      [các chương trình con]


                                                                           20
END Nhãn chương trình
    Ví dө: ViӃt chương trình hiӋn mӝt xâu lên màn hình:
    .model small
    .code
      org 100h
     begin:
      jmp var
         str db "hello world!$"
        var:
        lea dx,str
        mov ah,9
        int 21h

        mov ah,1
        int 21h

       mov ah,4ch
       int 21h
     end begin
a) Cҩu trúc chương trình dҥng .exe
    Cҩu trúc:
    .MODEL SMALL
    .STACK 100h
    .DATA
       Khai báo biӃn
    .CODE
    Nhãn chương trình:
       mov ax,@data
       mov ds,ax
       Thân chương trình
        mov ah,4ch
        int 21h
      END Nhãn chương trình
    Ví dө: Chương trình hiӋn mӝt xâu lên màn hình
    .model small



                                                          21
.stack 100h
       .data
         str db "hello world!$"
       .code
         begin:
          mov ax,@data
          mov ds,ax
          lea dx,str
          mov ah,9
          int 21h

          mov ah,1
          int 21h

          mov ah,4ch
          int 21h
        end begin

1.4.3.2. Các Directve (.MODEL, .STACK, .DATA, .CODE, ...)
a) Directive .MODEL
   Chͱc năng: Cho phép ngưӡi lұp trình xác lұp vùng nhӟ RAM thích hӧp cho
   chương trình.
   Cú pháp
. Model                                   KiӇu
Tiny                                      Code + data ” 64k
Small                                     Code ” 64k; data ” 64k
Compact                                   Code ” 64k; data • 64k
Medium                                    Code • 64k; data ” 64k
Large                                     Code • 64k; data • 64k
                                          1 array ” 64k
Huge                                      Code • 64k; data • 64k
                                          1 array • 64k

b) Directive .STACK




                                                                       22
Chͱc năng: Báo cho chương trình dӏch cӫa ASM biӃt xác lұp mӝt vùng nhӟ
RAM cho Stack. Vӟi lӋnh điӅu khiӇn này thì DOS sӁ xác lұp đӏa chӍ đҫu cӫa
ngăn xӃp và giá trӏ đó đưӧc đưa vào thanh ghi segment SS.
    Cú pháp: . stack đӝ dài (tính theo byte)
    Ví dө: . stack 100h
      NӃu không có khai báo . stack thì lҩy đӝ dài mһc đӏnh default.
c) Directive . DATA
     Chͱc năng: Báo cho chương trình dӏch cӫa ASM biӃt đӇ xác lұp mӝt vùng
nhӟ RAM cho dӳ liӋu chương trình.
     Cú pháp:
     .DATA
     Khai báo biӃn
     BiӃn trong ASM có ba loҥi: biӃn sӕ, biӃn xâu kí tӵ và biӃn trưӡng sӕ
     y Khai báo biӃn sӕ
      . DATA
      Tên_biӃn KiӇu Giá_trӏ_ban_đҫu/?
      Các kiӇu dӳ liӋu:
      db ( 1 byte)
      dw (2 byte)
      dd ( 4 byte)
      dp ( 6 byte)
      dq ( 8 byte)
      dt ( 10 byte)
      trong đó 2 biӃn db và dw hay dùng.
      Ví dө:
      .DATA Value dw ?
      Value db 10
     y Khai báo biӃn xâu kí tӵ
      . DATA
      Tên_biӃn db Các_kí_tӵ_cách_nhau_bӣi_dҩu_phҭy đӝ_lӟn dup (1 kí tӵ/
?)
      Ví dө:
      .DATA
      xau1 db µH¶,¶e¶,¶l¶,¶l¶,¶l,¶o¶
      xau2 db 100h dup(µA¶)
      xau2 db 100 dup(?)

                                                                        23
y Khai báo biӃn trưӡng sӕ
    .DATA
    Tên_trưӡng_sӕ       kiӇu_cӫa_thành_phҫn (Các sӕ cách nhau bӣi dҩu ',')
Đӝ_lӟn dup( 1 sӕ/?)
    Ví dө:
    .DATA
    array1 db 100,2,21,31
     array2 dw 100h dup(-100)
     Chú ý: NӃu chương trình có khai báo biӃn (tӭc là có .DATA) thì ngưӡi lұp
trình ASM phҧi đưa phҫn đӏa chӍ segment cӫa vùng nhӟ dӳ liӋu vào trong DS
nhӡ 2 lӋnh sau:
     mov reg16, @data
     mov ds,reg16
     Ví dө:
       mov ax, @data
       mov ds,ax
d) Directive .CODE
     Chͱc năng: Báo cho chương trình dӏch ASM biӃt đӇ xác lұp 1 vùng nhӟ
RAM cho phҫn tӱ mã máy cӫa chương trình.
     Cú pháp: .CODE

1.4.4. Cҩu trúc cӫa mӝt chương trình segment dҥng chuҭn
       Ta có thӇ hình dung dҥng thưӡng thҩy cӫa mӝt chương trình segment như
sau:
       Segment_Name SEGMENT
       ....
       ....
       ....
       Segment_Name ENDS
                         END
1.4.4.1. Chương trình segment đơn giҧn dҥng chuҭn
       Stack segment
           db 100h dup (?)
       Stack ends
       Data segment
           Khai báo biӃn


                                                                          24
Data ends
    Code segment
       Assume cs:code, ds:data, ss:stack
    Nhan CT:
       mov ax, data
       mov ds,ax
       mov ah, 4ch
       int 21h
    code ends
    END Nhan CT
1.4.4.2. Các directive điӅu khiӇn segment: dҥng chuҭn
(SEGMENT, GROUP và ASSUME)
a) Directive SEGMENT
     Chͱc năng: báo cho chương trình dӏch ASM xác lұp các segment cho
chương trình.
     Cú pháp:
     Khuân mүu đҫy đӫ cӫa chӍ dүn hưӟng SEGMENT là:
Segment_Name SEGMENT Align                  Combine    Use      Class
                            PARA(16 byte)      PUBLIC      USER16 Class
                            BYTE (1 byte)      COMMON USER32
                            WORD(2 byte)       STACK
                            DWORD(4 byte) AT
                            PAGE(128 byte)
    -Segment_Name: bҩt kǤ mӝt đӏnh danh nào. Tên segment chӍ đưӧc phép
bao gӗm mӝt tӯ, nӃu gӗm nhiӅu tӯ thì phҧi có dҩu gҥch dưӟi đӇ nӕi các tӯ vӟi
nhau. Các phҫn tӱ đӭng sau SEGMENT đӅu là tùy chӑn.
     - Align
    Cú pháp:
            Align
            PARA (16 byte)
            BYTE (1 byte)
            WORD (2 byte)
            DWORD (4 byte)
            PAGE (128 byte)




                                                                         25
Chͱc năng: xác lұp khoҧng trӕng giӳa segment đang khai báo vӟi segment
trưӟc nó. NӃu là BYTE thì khoҧng trӕng giӳa hai segment là 1 byte, PARA là 16
byte...




                                      hình:
              Xác lұp khoҧng trӕng giӳa hai segment là 1 byte (BYTE)
     NӃu như Align không đưӧc đӏnh nghĩa thì chӍ thӏ mһc đӏnh PARA sӁ đưӧc
sӱ dөng.
     - Combine
     Chӭc năng 1: cho phép đһt segment khai báo vào mӝt vùng nhӟ RAM theo
yêu cҫu.
     Cú pháp:
    tên segment SEGMENT đӏa chӍ
    ....
    ....
    ....
    Tên segment ENDS
    Chӭc năng 2: phөc vө chương trình đa tӋp thuҫn tuý ASM, cách gӝp các
segment có cùng tên nҵm ӣ các tӋp khác nhau khi liên kӃt.
    Cú pháp:
     COMMON          Tҩt cҧ các đoҥn cùng tên đưӧc nҥp chӗng lên nhau, sao
                     cho tҩt cҧ đӅu bҳt đҫu ӣ cùng mӝt đӏa chӍ. Khi đó đoҥn
                     tәng cӝng sӁ lӟn bҵng đoҥn riêng lҿ lӟn nhҩt
     PUBLIC          Các đoҥn cùng tên sӁ đưӧc kӃt nӕi vӟi nhau thành mӝt
                     đoҥn duy nhҩt.
     PRIVATE         Mӛi đoҥn nҵm trong mӝt đoҥn vұt lý riêng.
     (Default)
    - USE : chӍ có tӯ thӃ hӋ 80386 và chӍ đưӧc dùng vӟi chӍ dүn hưӟng 386.


                                                                             26
use16 ASM 16 bit (default): Đӝ dài đoҥn cӵc đҥi là 64Kbyte
    use32 ASM 32 bit : Đӝ dài đoҥn cӵc đҥi là 4Gbyte.
    - µCLASS¶
    Chӭc năng: cho phép gӝp các segment có cùng lӟp lҥi gҫn nhau khi liên kӃt.
Tên lӟp phҧi đưӧc đһt trong dҩu nháy đơn '', có thӇ dùng mӝt tên bҩt kǤ. Tҩt cҧ
các segment có cùng tên nhưng có tên lӟp khác nhau sӁ đưӧc nҥp kӃ tiӃp nhau
vào trong bӝ nhӟ. Thông thưӡng thì ta chӍ cҫn có mӝt tên lӟp khi ta muӕn kӃt nӕi
các chương trình hӧp ngӳ vӟi các chương trình ngôn ngӳ bұc cao.




    Cách khai báo 3 segment cӫa chương trình:
      Dҥng chuҭn                        Dҥng đơn giҧn
      Stack segment
      db 100h dup (?)                   .Stack 100h
      Stack ends
      Data segment                      .DATA
      Khai báo biӃn                     Khai báo biӃn
      Data ends
      Chú ý: mov ax, data               Chú ý: mov ax,@data
      mov ds, ax                        mov ds, ax
      Code segment                      .CODE
      Nhan CT:                          Nhan CT:
      Code ends                         ENDS Nhan CT
      ENDS Nhan CT
b) Drective GROUP



                                                                             27
Chͱc năng: gӝp các segment cùng loҥi cho dӉ dàng qui chiӃu.
Cú pháp:
tên nhóm GROUP tên các segment
Khai báo các segment
Gi̫i thích:
Data1     segment
         M1 db ?
Data1     ends
Data2     segment
         M2 dw ?
Data2    ends
Code     segment
PS:
      mov ax, data1
      mov ds,ax
      mov cl, M1
      mov ax, data2
      mov ds,ax
      mov cl, M2
Ta làm group như sau:
Nhom_DL GROUP data1,data2
Data1 segment
        M1 db ?
Data1 ends
Data2 segment
        M2 dw ?
Data2 ends
Code segment
PS:
     mov ax, nhom_DL
     mov cl, M1
     mov dx,M2
c) Directive ASSUME
Chͱc năng: cho biӃt segment khai báo thuӝc loҥi segment nào
Cú pháp:
assume tên thanh ghi segment : tên segment


                                                              28
Gi̫i thích:




assume cs:x3, ds:x2,ss:x1
Chú ý: assume thưӡng là dòng đҫu cӫa code segment
Ví dө: HiӋn xâu kí tӵ "hello world !$"
stack segment
   db 100h dup(?)
ends stack
data segment
  str db "hello world!$"
ends data
code segment
  assume ss:stack,cs:code,ds:data
  begin:
  mov ax,data
  mov ds,ax
  lea dx,str
  mov ah,9
  int 21h
  mov ah,1
  int 21h
  mov ah,4ch
  int 21h
ends code
end begin



                                                    29
Chương 2. Lұp trình vӟi Debug

2.1. Tәng quan vӅ Debug
2.1.1. Đһc điӇm cӫa Debug
     Debug là mӝt chương trình chҥy trong môi trưӡng DOS. Nó dùng đӇ cho
ngưӡi lұp trình có thӇ:
    y nhұp và dӏch các lӋnh dҥng hӧp ngӳ sang mã máy và ngưӧc lҥi
    y nҥp, xem và thay đәi nӝi dung cӫa tӋp ӣ trong khӕi nhӟ
    y chҥy chương trình theo tӯng lӋnh, nhóm lӋnh hay cҧ chương trình
    y sӱa tӯng byte, nhiӅu byte hay cҧ chương trình
     y xem và thay đәi nӝi dung các thanh ghi
     Các lӋnh cӫa debug đӅu bҳt đҫu bҵng mӝt hay hai chӳ cái, trong đó có mӝt
dҩu ?
2.1.2. Khӣi đӝng và thoát khӓi Debug
     Khӣi đӝng Debug tҥi dҩu nhҳc cӫa DOS ta gõ lӋnh:
     Debug [ә đĩa][đưӡng dүn][tên tӋp]
     Trong đó các tham sӕ đi đҵng sau lӋnh Debug dùng đӇ chӍ ra tên tӋp .EXE
hay .COM đӇ kiӇm tra.
     Sau khi khӣi đӝng Debug thì màn hình lúc này còn mӝt dҩu nhҳc là dҩu
gҥch ngang nhӓ "_". Tҥi đây ta gõ các lӋnh cӫa Debug đӇ thӵc hiӋn kӃt thúc lӋnh
là ENTER và muӕn thoát khӓi Delbug ta gõ lӋnh q (quit).

2.2. Các lӋnh cӫa Debug
2.2.1. Nhóm các lӋnh biên soҥn chương trình
1) LӋnh A
      Cú pháp: A [address]
      Thông sӕ address: là mӝt sӕ hexa gӗm 4 chӳ sӕ đӇ chӍ đӏa chӍ bҳt đҫu các
lӋnh dҥng hӧp ngӳ cӫa chương trình. Đӏa chӍ có thӇ là CS:Offset hay chӍ có đӏa
chӍ Offset vì ngҫm đӏnh là CS hiӋn hành. NӃu không có tham sӕ address thì lҩy
đӏa chӍ CS:Offset hiӋn hành mà lӋnh trưӟc dùng tҥi đó.
      Công dөng: LӋnh cho ta nhұp các lӋnh cӫa chương trình dҥng hӧp ngӳ vào
mӝt đӏa chӍ ô nhӟ.
      Ví dө: A 200 hay A 0200
      Khi đó màn hình sӁ hiӋn ra đӏa chӍ ô nhӟ xxxx:0200 đӇ ta gõ lӋnh vào đӏa
chӍ trên, ví dө ta gõ lӋnh MOV AX, 09 (các giá trӏ trong Debug đӅu ӣ dҥng hexa


                                                                            30
nên ta không cҫn đưa thêm ký tӵ h đҵng sau giá trӏ đó. NӃu có nó sӁ báo lӛi). Sau
khi nhҩn Enter thì dòng lӋnh đưӧc:
      y dӏch ra mã máy
      y ghi vào ô nhӟ có đӏa chӍ trên
      y màn hình hiӋn ra đӏa chӍ tiӃp theo đӇ chӡ nhұp lӋnh tiӃp theo
     Cӭ tiӃp tөc như vұy ta có thӇ nhұp đưӧc cҧ chương trình
2) LӋnh E
      Cú pháp: E <address> [list]
      Thông sӕ address là mӝt sӕ hexa gӗm bӕn chӳ sӕ đӇ chӍ đӏa chӍ bҳt đҫu đӇ
xem hay sӱa đәi dӳ liӋu. Đӏa chӍ có thӇ là CS:Offset hay chӍ là Offset vì ngҫm
đӏnh là CS hiӋn hành.
      Thông sӕ list là danh sách các dӳ liӋu mà ta muӕn nhұp vào các ô nhӟ liên
tiӃp. NӃu là mӝt xâu ký tӵ thì tâ phҧi đһt trong hai dҩu nháy kép "" hay hai dҩu
nháy đơn ''.
      Công dөng: Dùng đӇ xem và sӱa nӝi dung cӫa tӯng ô nhӟ. Ta chӍ cҫn chӍ
ra đӏa chӍ đҫu tiên cӫa ô nhӟ và khi đó nó sӁ hiӋn ra nӝi dung cӫa ô nhӟ đҫu tiên,
nӃu ta muӕn sӱa dӳ liӋu cӫa ô nhӟ thì ta cӭ viӋc nhұp dӳ liӋu mӟi bên cҥnh dӳ
liӋu cũ, sau đó nhҩn dҩu cách đӇ xem nӝi dung cӫa ô nhӟ tiӃp theo. KӃt thúc lӋnh
này là dҩu Enter.
3) LӋnh F
     Cú pháp: F range list
     Thông sӕ range xác đӏnh mӝt vùng nhӟ, có thӇ là đӏa chӍ bҳt đҫu và đӏa chӍ
kӃt thúc hay đӏa chӍ bҳt đҫu và chiӅu dài cӫa vùng nhӟ.
     thông sӕ list chӍ danh sách các dӳ liӋu muӕn lҩp đҫy vùng nhӟ range
     Công dөng: Lҩp đҫy các ô nhӟ bҵng mӝt danh sách các dӳ liӋu. LӋnh này
có thӇ thay cho lӋnh E đӇ nhұp đӗng thӡi nhiӅu dӳ liӋu cùng mӝt lúc.
     Ví dө: F 0100 L 100 41 42 43
     LӋnh này sӁ ghi đҫy các ô nhӟ tӯ 0100 đӃn 01FF (100 đӏa chӍ) bҵng các con
sӕ 41, 42, 43. Ba giá trӏ này sӁ lһp lҥi cho đӃn khi toàn bӝ các ô nhӟ đưӧc lҩp
đҫy giá trӏ.
     Ví dө 2: F 0100 0120 41 42
     LӋnh này sӁ lҩp đҫy các ô nhӟ trong vùng tӯ 0100 đӃn 0120 (21 ô nhӟ) bӣi
các giá trӏ 41, 42.
4) LӋnh U
     Cú pháp: U [range]


                                                                               31
Thông sӕ range xác đӏnh đӏa chӍ đҫu và đӏa chӍ cuӕi hay đӏa chӍ đҫu và chiӅu
dài ô nhӟ.
     Công dөng: Có thӇ nói lӋnh này trái ngưӧc vӟi lӋnh A, nó dӏch ngưӧc các
lӋnh tӯ mã máy sang lӋnh dҥng assembly trong các ô nhӟ đưӧc chӍ ra vùng range
hay đӏa chӍ IP hiӋn hành.
     Ví dө:
     U 0100 : Dӏch ngưӧc 32 byte đҫu tiên tӯ đӏa chӍ 0100
     U CS:0100 110 : Dӏch ngưӧc dӳ liӋu tӯ đӏa chӍ CS:0100 tӟi CS: 110
     U 0100 L 20 : Dӏch ngưӧc 20 dòng lӋnh bҳt đҫu tӯ đӏa chӍ 0100
2.2.2. Nhóm các lӋnh dӏch chuyӇn dӳ liӋu
1) LӋnh I
       Cú pháp: I <đӏa chӍ cәng>
       Thông sӕ đӏa chӍ cәng vào có thӇ mã hóa thành 16 bit
       Công dөng: Đӑc giá trӏ cӫa cәng có đӏa chӍ đưӧc chӍ ra
       Ví dө: I 2F8 : Đӑc giá trӏ cӫa cәng có đӏa chӍ là 2F8 và in giá trӏ lên màn
hình
2) LӋnh O
       Cú pháp: O <Đӏa chӍ cӗng> <giá trӏ>
       Thông sӕ đӏa chӍ cәng giӕng lӋnh I
       Thông sӕ giá trӏ là byte sӕ liӋu đưa ra cәng
       Công dөng: LӋnh này đưa mӝt byte dӳ liӋu ra cәng
       Ví dө: O 61 3A : Đưa giá trӏ 3A ra cәng 61
3) LӋnh L
     Cú pháp:
     Dҥng 1: L [address] ghi nӝi dung cӫa mӝt sӕ byte đã đưӧc chӍ đӏnh trong
thanh ghi BX:CX cӫa mӝt tӋp lên đĩa.
     Dҥng 2: L address driver firstsector numer nҥp trӵc tiӃp các cung đưӧc
chӍ đӏnh
     Thông sӕ address là đӏa chӍ mà ӣ đó ta muӕn nҥp tӋp hay nӝi dung cӫa
cung. NӃu không chӍ đӏnh đӏa chӍ thì Debug sӁ lҩy đӏa chӍ mһc đӏnh trong CS.
     Thông sӕ Driver chӍ đӏnh ә đĩa trên đó các cung chӍ đӏnh sӁ đưӧc đӑc. Có
các giá trӏ 0=ә A, 1=ә B, 2=ә C,...
     Thông sӕ Fistsector là mӝt sӕ hexa chӍ sӕ cung đӇ nҥp
     Thông sӕ number là mӝt sӕ hexa chӍ sӕ các cung liên tiӃp sӁ đưӧc đӑc.



                                                                               32
Công dөng: Dҥng 1 nҥp nӝi dung cӫa tӋp tin có tên N vào bӝ nhӟ cӫa máy
tính có đӏa chӍ là address. NӃu không có đӏa chӍ thì máy sӁ lҩy đӏa chӍ CS:0100.
Cһp thanh ghi BX:CX sӁ chӭa kích thưӟc tӋp.
     Dҥng 2: Nҥp nӝi dung các cung trên đĩa vào bӝ nhӟ bҳt đҫu tӯ đӏa chӍ
address. Sector đҫu tiên trên đĩa cҫn đưӧc xác đӏnh trong firstsector và sӕ sector
cҫn đӑc đưӧc cho vào trong number.
     Ví dө: Nҥp tӋp a.txt vào đӏa chӍ bҳt đҫu là CS:0000h
     y N a.txt
     y L0
     Ví dө: Nҥp 5 sector đҫu tiên cӫa đĩa A vào bӝ nhӟ có đӏa chӍ là DS:0000h:
     L DS:0000 0 1 5
4) LӋnh N
     Cú pháp: N [driver][đưӡng dүn]<tên tӋp>
     Công dөng: LӋnh này đһt tên cho tӋp sҳp ghi hay tӋp đã tӗn tҥi đӇ đӑc vào
bӝ nhӟ.
     Ví dө:
     N C:test.txt
     R CX
     100
     W 0100
     Hai lӋnh này sӁ ghi 100 byte bҳt đҫu tҥi đӏa chӍ 0100 vào tӋp test.txt trong ә
đĩa C.
5) LӋnh W
     Cú pháp:
     Dҥng 1: W[address]
     Ghi nӝi dung cӫa sӕ byte đưӧc chӍ trong BX:CX bҳt đҫu tҥi address vào tӋp
có tên đưӧc đһt bӣi lӋnh N
     Dҥng 2: W address driver firstsector number
     Các tham sӕ giӕng lӋnh L
     Ví dө: W 0000 0 200 10 : Ghi 10 sector trong bӝ nhӟ bҳt đҫu tҥi đӏa chӍ
CS:0000 vào sector thӭ 200 cӫa đĩa A.
6) LӋnh M
     Cú pháp: M range address
     Thông sӕ range chӍ đӏnh các đӏa chӍ bҳt đҫu hoһc kӃt thúc hay đӏa chӍ bҳt
đҫu và chiӅu dài vùng nhӟ mà ta muӕn chép nӝi dung.


                                                                                33
Thông sӕ address là đӏa chӍ bҳt đҫu mà ta muӕn chép nӝi dung cӫa vùng
nhӟ range đӃn
     Công dөng: Chép nӝi dung cӫa vùng nhӟ range sang vùng khác có đӏa chӍ
bҳt đҫu là address.
     Ví dө: M 0100 2FE 3000:0000 : ChuyӇn vùng dӳ liӋu tӯ DS:0100 đӃn
DS:02FE sang vùng nhӟ bҳt đҫu là 3000:0000
2.2.3. Nhóm lӋnh quan sát
1) LӋnh ?
    LӋnh này hiӋn nӝi dung cӫa các lӋnh cӫa Debug và chӍ dүn (lӋnh HELP)
2) LӋnh R
    Cú pháp: R [register]
    LӋnh này nӃu không có tham sӕ register thì nó sӁ cho hiӋn nӝi dung tҩt cҧ
các thanh ghi cӫa vi xӱ lý kӇ cҧ thanh ghi cӡ.
     NӃu có tham sӕ register thì lӋnh này cho hiӋn nӝi dung cӫa thanh ghi đó và
cho phép thay đәi nӝi dung cӫa thanh ghi đó.
4) LӋnh D
    Cú pháp: D [address] hay D[range]
    Thông sӕ address là đӏa chӍ bҳt đҫu cӫa mӝt vùng nhӟ 128 byte đӇ hiӇn thӏ
    Thông sӕ range là đҥi chӍ đҫu và đӏa chӍ cuӕi hay đӏa chӍ đҫu và đӝ dài cӫa
vùng nhӟ đӇ hiӇn thӏ.
5) LӋnh C
     Cú pháp: C range address
     Thông sӕ range chӍ đӏnh đӏa chӍ bҳt đҫu và kӃt thúc hay đӏa chӍ bҳt đҫu và
chiӅu dài cӫa vùng nhӟ thӭ nhҩt đӇ so sánh.
     Thông sӕ address chӍ đӏnh đӏa chӍ bҳt đҫu cӫa vùng nhӟ thӭ hai cӫa khӕi
nhӟ đӇ so sánh.
     Công dөng: LӋnh này sӁ so sánh hai vùng nhӟ trên nӃu giӕng nhau toàn bӝ
thì Debug không hiӋn thông báo gì cҧ. Còn nӃu không đӗng nhҩt thì Debug sӁ
hiӇn thӏ nӝi dung cӫa các ô nhӟ khác nhau.
2.2.4. Nhóm lӋnh thi hành chương trình
1) LӋnh T
    Cú pháp: T [=address][value]
    Thông sӕ =address chӍ đӏnh đӏa chӍ mà Debug phҧi bҳt đҫu thӵc hiӋn. NӃu
không có tham sӕ này thì Debug thӵc hiӋn tӯ đӏa chӍ trong cһp CS:IP.


                                                                            34
Thông sӕ value chӍ sӕ lӋnh cҫn thӵc hiӋn, giá trӏ ngҫm đӏnh là 1
     Công dөng: Thӵc hiӋn tӯng lӋnh mӝt hay mӝt sӕ các lӋnh. Sau mӛi lӋnh thì
nӝi dung các thanh ghi cӡ và thanh ghi chӭc năng đưӧc hiӋn lên màn hình cùng
vӟi câu lӋnh tiӃp theo.
2) LӋnh P
    Cú pháp: P [=address][range]
    Thông sӕ: Các thông sӕ giӕng lӋnh T
    Công dөng: LӋnh này cũng thӵc hiӋn tӯng lӋnh mӝt giӕng lӋnh T chӍ có
mӝt điӇm khác là khi gһp lӋnh gӑi chương trình con, lӋnh lһp hay lӋnh ngҳt thì
nó thӵc hiӋn cҧ nhóm lӋnh trên.
3) LӋnh G
    Cú pháp: G [=address][điӇm dӯng]
      Thông sӕ address giӕng lӋnh T
      Thông sӕ điӇm dӯng chӍ đӏnh điӇm dӯng cho lӋnh G
      Công dөng: LӋnh này thӵc hiӋn toàn bӝ chương trình hay thӵc hiӋn tӯ đҫu
đӃn điӇm dӯng. Mӝt điӅu khác biӋt so vӟi lӋnh P và T là con trӓ lӋnh IP không
tăng.
      Ví dө: G=0100 hay G : Thӵc hiӋn toàn bӝ chương trình bҳt đҫu tҥi đӏa chӍ
CS:0100
    G =0100 200 : Thӵc hiӋn chương trình tӯ cs:0100 đӃn cs:0200




                                                                           35
Chương 3: Các lӋnh cӫa Assembly

3.1 Các lӋnh vұn chuyӇn dӳ liӋu
     Tҩt cҧ lӋnh trong nhóm này khi thӵc hiӋn không làm thay đәi trҥng thái cӫa
các bit cӡ.
1) LӋnh mov
     Chͱc năng: Đưa nӝi dung tӯ SRC đӃn DST
       Cú pháp: mov DST, SRC
reg1                        reg2                      mov ax, bx
reg                         data                      mov cx,100
reg                         mem                       mov dx,value
mem                         reg                       mov value,dx
mem                         data                      mov value,100
segreg                      reg16                     mov ds,ax
reg16                       segreg                    mov bx,cs
segreg                      mem                       16 mov cs,value
mem16                       segreg                    mov value,cs
       Chú ý:
       y Không đưӧc di chuyӇn giӳa hai biӃn nhӟ (mov mem1,mem2).
       Thӵc hiӋn gián tiӃp:
       mov reg,mem2
       mov mem1,reg
       y Không đưa trӵc tiӃp dӳ liӋu vào thanh ghi segment (mov seg,data).
       Thӵc hiӋn gián tiӃp:
       mov reg16,data
       mov segreg,reg16
       y Sӵ khác nhau khi sӱ dөng các chӃ đӝ đӏa chӍ
       ( mov ax,bx khác vӟi mov ax,[bx] ; đưa nӝi dung mà bx trӓ đӃn vào ax)
       mov ax,[bx] tương đương vӟi
       mov ax, ds:[bx] (SI,DI hay BP)
2) LӋnh push
     Chͱc năng: cҩt 2 byte cӫa SRC vào đӍnh ngăn xӃp(stack).
     Cú pháp:
PUSH                                      SRC
                                          Reg16


                                                                               36
Mem16
     Ví dө: push ax
     Toán hҥng gӕc có thӇ tìm đưӧc theo các chӃ đӝ đӏa chӍ khác nhau: có thӇ là
thanh ghi đa năng, thanh ghi đoҥn hay là ô nhӟ. LӋnh này thưӡng đưӧc dùng vӟi
lӋnh POP như là mӝt cһp đӛi ngүu đӇ xӱ lý các dӳ liӋu và trҥng thái cӫa chương
trình chính(CTC) khi vào ra chương trình con(ctc).
3) LӋnh POP
     Chͱc năng: lҩy 2 byte (1 tӯ) ӣ đӍnh ngăn xӃp (stack) vào toán hҥng đích.
     Cú pháp:
POP                                      DST
                                         Reg16
                                         Mem16
      Ví dө:
      push ax
      push bx
      push cx
      Đoҥn chương trình:
     Pop cx
     Pop bx
     Pop ax
     Chú ý:
     - Cơ chӃ PUSH/POP là LIPO( last in first out)
     - Cách viӃt trên chӍ đưӧc sӱ dөng trong MASM còn trong TASM đưӧc viӃt
như sau:
      push ax bx cx
4) LӋnh PUSHF
     Chͱc năng: cҩt giá trӏ thanh ghi cӡ vào đӍnh ngăn xӃp
     Cú pháp: PUSHF
     Dӳ liӋu tҥi ngăn xӃp không thay đәi, SS không thay đәi.
5) LӋnh POPF
     Chͱc năng: Lҩy 2 byte tӯ đӍnh ngăn xӃp rӗi đưa vào thanh ghi cӡ.
     Cú pháp: POPF
     Sau lӋnh này dӳ liӋu tҥi ngăn xӃp không thay đәi, SS không thay đәi.
6) LӋnh XCHG (Exchange 2 Operands) Tráo nӝi dung 2 toán hҥng
     Chͱc năng: Tráo nӝi dung 2 toán hҥng DST và SRC
      Cú pháp:



                                                                                37
XCHG                       DST                         SRC
                           Reg1                        Reg2
                           Reg                         Mem
     Trong toán hҥng đích có thӇ tìm theo chӃ đӝ đӏa chӍ khác nhau nhưng phҧi
chӭa dӳ liӋu có cùng đӝ dài và không đưӧc phép đӗng thӡi là 2 ô nhӟ và cũng
không đưӧc là thanh ghi đoҥn. Sau lӋnh XCHG toán hҥng chӭa nӝi dung cũ cӫa
toán hҥng kia và ngưӧc lҥi.
     LӋnh này không tác đӝng đӃn cӡ.
7) LӋnh IN
     Chͱc năng: đӑc dӳ liӋu tӯ cәng vào thanh ghi AL/AX
     Cú pháp: IN AL/AX, đӏa chӍ cәng
     Chú ý:
     + NӃu đӏa chӍ cәng <256 thì sӕ đӏa chӍ đӭng trӵc tiӃp trong lӋnh IN
     Ví dө: đӏa chӍ cәng là 1fh
     IN AL,1fh ; nӝi dung cәng 1fh đưa vào AL.
    + NӃu đӏa chӍ cәng • 256 thì phҧi nhӡ đӃn thanh ghi DX
    Ví dө: đӏa chӍ COM1 = 378h
    mov dx,378h
    in al,dx
8) LӋnh OUT
     Chͱc năng: đưa dӳ liӋu tӯ thanh ghi AL/AX ra cәng
    Cú pháp: OUT đӏa chӍ cәng,AL/AX
    Chú ý:
    y NӃu đӏa chӍ cәng <256 thì sӕ đӏa chӍ đӭng trӵc tiӃp trong lӋnh OUT
    Ví dө: đӏa chӍ cәng là 1fh
    OUT 1fh,AL ; nӝi dung cәng 1fh đưa vào AL.
    y NӃu đӏa chӍ cәng • 256 thì phҧi nhӡ đӃn thanh ghi DX
    Ví dө: đӏa chӍ COM1 = 378h
    mov dx,378h
    out dx,al
    LӋnh này không tác đӝng đӃn cӡ.
9) LӋnh LEA (load Efective address)
     Chͱc năng: lҩy phҫn đӏa chӍ offset cӫa biӃn đưa vào thanh ghi 16 bit
     Cú pháp: lea reg16, mem
     Ví dө: lea bx, Value hay mov bx, OFFSET Value
     Đích thưӡng là các thanh ghi: BX, CX, DX, BP, SI, DI.


                                                                            38
Nguӗn là tên biӃn trong đoҥn DS đưӧc chӍ rõ trong lӋnh hay ô nhӟ cө thӇ.
    Ví dө: lea dx, msg; Nҥp đӏa chӍ offset cӫa bҧn tin msg vào dx.




10) LӋnh LES (Load register and ES with words from memory)
      Chӭc năng: chuyӇn giá trӏ cӫa 1 tӯ tӯ mӝt vùng nhӟ vào thanh ghi đích và
giá trӏ cӫa tӯ tiӃp theo sau cӫa vùng nhӟ vào thanh ghi ES.
      Cú pháp: les reg, mem
      Trong đó: Đích là mӝt trong các thanh ghi AX, BX,CX, DX, SP, BP, SI, DI.
      Gӕc là ô nhӟ trong đoҥn DS đưӧc chӍ rõ trong lӋnh




11) LӋnh LDS (Load resgister and DS with words from memory)
     Chӭc năng: Nҥp mӝt tӯ tӯ bӝ nhӟ vào thanh ghi cho trong lӋnh và 1 tӯ tiӃp
theo vào DS.
    Cú pháp: lds reg, mem




3.2 Các lӋnh sӕ hӑc
1) LӋnh ADD(addition)
     Chӭc năng: DST ĸDST + SRC
     Cӝng hai toán hҥng: lҩy toán hҥng đích cӝng vӟi toán hҥng nguӗn rӗi đưa
vào toán hҥng đích.
     Cú pháp:




                                                                               39
Tác đӝng đӃn cӡ: C, P, A, Z, S, O.
2) LӋnh ADC(Add with carry)
     Chӭc năng: cӝng có nhӟ, DSTĸ DST + SRC + CF
     Cú pháp: adc DST, SRC
     Tác đӝng đӃn cӡ: C, P, A, Z, S, O.
    Ví dө: adc ax, bx




3) LӋnh INC(Increment Destination Register or Memory)
     Chӭc năng: Tăng toán hҥng đích thêm 1. DSTĸ DST + 1
     Cú pháp: inc DST
     Tác đӝng đӃn cӡ: C, P, Z, S, O.
     Ví dө: regĺ inc ax
     memĺ inc value
4) LӋnh INC(Increment Destination Register or Memory)
     Chӭc năng: Tăng toán hҥng đích thêm 1. DST ĸDST + 1
     Cú pháp: inc DST
     Tác đӝng đӃn cӡ: C, P, Z, S, O.
     Ví dө: regĺ inc ax
     memĺ inc value
5) LӋnh SUB (Substraction)
     Chӭc năng: Trӯ hai toán hҥng, DSTĸ DST ± SRC
     Cú pháp: sub DST, SRC
     Ví dө: sub ax, bx
     Tác đӝng đӃn cӡ: C, P, A, Z, S, O.
     Chú ý: chӃ đӝ đӏa chӍ không đưӧc đӗng thӡi là 2 ô nhӟ hay là thanh ghi
đoҥn.
6) LӋnh SBB (Substraction with borrow)
     Chӭc năng: Trӯ có mưӧn, DST ĸDST ± SRC ± CF
     Cú pháp: sbb DST, SRC
     Ví dө: sbb ax, bx
     Tác đӝng đӃn cӡ: C, P, A, Z, S, O.




                                                                        40
7) LӋnh MUL/ IMUL (Multiply Unsigned Byte or Word/ Integer
Multiplication )
     Chӭc năng: Nhân 2 toán hҥng vӟi sӕ không dҩu (MUL), sӕ có dҩu (IMUL)
     Cú pháp:




    Có hai trưӡng hӧp tә chӭc phép nhân
    y 8 bits * 8 bits
    Sӕ bӏ nhân phҧi là sӕ 8 bit đӇ trong AL
    Sau khi nhân: al*SRC AX
    y 16 bits * 16 bits
    Sӕ bӏ nhân phҧi là sӕ 16 bit đӇ trong AX
    Sau khi nhân: ax*SRC dx:ax
    Tác đӝng đӃn cӡ: C, O.
    Chú ý:
    al = 1111 1111
    bl = 0000 0010
    mul bl ax = al*bl (255*2 = 510)
     imul bl ax = al*bl (- 1*2 = -2 )
     Trong phép chia thì ax, bx, dx (al,bl,dx) là ҭn
8) LӋnh DIV/IDIV(Unsigned Divide/Integer Division)
     Chӭc năng: Chia hai toán hҥng vӟi sӕ không dҩu/ sӕ có dҩu
     Cú pháp:



    Hai trưӡng hӧp tә chӭc phép chia
    y NӃu sӕ 16 bits chia cho sӕ 8 bits




    y NӃu sӕ 32 bits chia cho sӕ 16 bits

                                                                        41
Trong phép chia thì ax, bx, dx (al,bl,dx) là ҭn
    Ví dө:




9) LӋnh DEC (Decrement Destination Register or Memory)
     Chӭc năng: Giҧm toán hҥng đích đi 1, DSTĸ DST ± 1
     Cú pháp: dec DST
    regĺ dec ax
    mem ĺdec value
    Tác đӝng đӃn cӡ: C, P, Z, S, O.
10) LӋnh NEG (Negate a Operand)
     Chӭc năng: lҩy bù hai cӫa mӝt toán hҥng, đҧo dҩu cӫa mӝt toán hҥng
     DST ĸ - DST
     Cú pháp: neg DST
     regĺ neg ax
     mem ĺneg value
     Tác đӝng đӃn cӡ: C, P, A, Z, S, O.
     11) LӋnh CMP (Compare Byte or Word)
     Chӭc năng: So sánh nӝi dung cӫa hai toán hҥng và dӵng cӡ. Sau khi thӵc
hiӋn lӋnh này nӝi dung cӫa hai toán hҥng không thay đәi.
    Cú pháp: cmp DST, SRC
    Tác đӝng đӃn cӡ: C, P, Z, S, O.
    Cách dӵng cӡ:
    cmp DST, SRC
    y NӃu DST < SRC thì CF = 1.
    y NӃu DST • SRC thì CF = 0.
    y NӃu DST = SRC thì ZF = 1.
    y NӃu DST  SRC thì ZF = 0.


                                                                          42
3.3 Các lӋnh thao tác mӭc bit
     Chú ý: tҩt cҧ các lӋnh trong nhóm này khi thӵc hiӋn có thӇ làm thay đәi
trҥng thái các bit cӡ.
1) LӋnh AND
     Chӭc năng: Thӵc hiӋn phép ³và logic´, bit cӫa kӃt quҧ bҵng 1 khi 2 bit
tương ӭng đӅu bҵng 1. DSTĸ DST ȁ SRC
    Ví dө:
    al = 1010 1010
    bl = 1100 1100
    and al,bl = 1000 1000
    Cú pháp: and DST, SRC
    Cách hay dùng:
    y Tách bit:
    al = xxxx xxxx
         0001 0000
     and al, 10h = 000x 0000
     Khi dùng phép AND đӇ che đi/ giӳ lҥi mӝt vài bit nào đó cӫa mӝt toán hҥng
thì bҵng cách nhân logic toán hҥng đó vӟi toán hҥng tӭc thì có các bit0/1 ӣ các
chӛ cҫn che/ giӳ nguyên tương ӭng.
    y Dӵng cӡ and DST,DST
    Ví dө: and ax, ax
    NӃu ax < 0 thì SF = 1.
    NӃu ax • 0 thì SF = 0.
    NӃu ax = 0 thì ZF = 1.
    NӃu ax  0 thì ZF = 0.
2) LӋnh OR
      Chӭc năng: thӵc hiӋn phép hoһc logic, Bit cӫa kӃt quҧ = 1 khi 1 trong 2 bit
là 1.
      DST ĸDST V SRC
    Ví dө:
    al = 1010 1010
    bl = 1100 1100
    or al,bl = 1110 1110
    Cú pháp: or DST, SRC
    Tác đӝng đӃn cӡ: C = O = 0, P, Z, S.
3) LӋnh XOR


                                                                              43
Chӭc năng: Thӵc hiӋn phép ³hoһc loҥi trӯ´ 2 toán hҥng, bit cӫa kӃt quҧ
bҵng 1 khi 2 bit tương ӭng khác nhau.
    Ví dө:
    al = 1010 1010
    bl = 1100 1100
    xor al,bl = 0110 0110
    Cú pháp: xor DST, SRC
    Cách hay dùng:
    y Tách bit:
    al = xxxx xxxx
         0001 0000
    and al, 10h = 000x 0000
    Tác đӝng đӃn cӡ: C = O = 0, P, Z, S.
    Ví dө: Thӵc hiӋn ax = 0
    1.   mov ax,0 ; 3 byte
    2.   and ax,0
    3.   sub ax,ax ; 2 byte
    4.   xor ax,ax
4) LӋnh SHL (Shift Left)
     Chӭc năng: dӏch trái các bit cӫa toán hҥng đích đi mӝt sӕ lҫn nào đó (sӕ lҫn
dӏch đưӧc cҩt trong thanh ghi CL).
     Cú pháp: SHL DST, CL
     (reg, mem)




     Tác đӝng đӃn cӡ: C, P, Z, S, O.
     Mӛi mӝt lҫn dӏch MSB sӁ đưa qua cӡ CF và đưa 0 vào LSB. CL chӭa sӕ lҫn
dӏch mong muӕn.
     NӃu dӏch mӝt lҫn thì ta có thӇ viӃt trӵc tiӃp.
     VD: shl ax,1
     NӃu sӕ lҫn dӏch • 2 thì phҧi nhӡ đӃn CL/CX
     shl ax, 4 Ł mov cl/cx, 4
                 shl ax, cl/cx
    Ý nghĩa: Dӏch trái 1 lҫn là nhân 2 vӟi sӕ nguyên dương.
5) LӋnh SHR (Shift Right)



                                                                              44
Chӭc năng: dӏch phҧi logic các bit cӫa toán hҥng đích đi mӝt sӕ lҫn nào đó
(sӕ lҫn dӏch đưӧc cҩt trong thanh ghi CL).
     Cú pháp: SHR DST, CL
     (reg, mem)




    Tác đӝng đӃn cӡ: C, P, Z, S, O.
     Mӛi mӝt lҫn dӏch LSB sӁ đưa qua cӡ CF và đưa 0 vào MSB. CL chӭa sӕ lҫn
dӏch mong muӕn.
     NӃu dӏch mӝt lҫn thì ta có thӇ viӃt trӵc tiӃp.
     VD: shr ax,1
     NӃu sӕ lҫn dӏch • 2thì phҧi nhӡ đӃn CL/CX
     shr ax, 4 Ł mov cl/cx, 4
                shr ax, cl/cx
    Ý nghĩa: Dӏch phҧi 1 lҫn là chia đôi và làm tròn dưӟi vӟi sӕ nguyên dương
6) LӋnh SAR ( Shift Arithmetically Right)
     Chӭc năng: dӏch phҧi sӕ hӑc các bit cӫa toán hҥng đích đi mӝt sӕ lҫn nào đó
(sӕ lҫn dӏch đưӧc cҩt trong thanh ghi CL).
     Cú pháp: SAR DST, CL
     (reg, mem)




     Tác đӝng đӃn cӡ: C, P, Z, S, O.
     Mӛi mӝt lҫn MSB đưӧc giӳ lҥi ( nӃu ta hiӇu đây là bit dҩu cӫa mӝt sӕ nào
đó thì dҩu luôn không đәi sau phép dӏch phҧi sӕ hӑc) còn LSB đưӧc đưa vào cӡ
CF. CL chӭa sҹn sӕ lҫn dӏch mong muӕn.
     NӃu dӏch mӝt lҫn thì ta có thӇ viӃt trӵc tiӃp.
    VD:sar ax,1
    NӃu sӕ lҫn dӏch • 2thì phҧi nhӡ đӃn CL/CX
    sar ax, 4 Ł mov cl/cx, 4
                sar ax, cl/cx
    Ý nghĩa: Dӏch phҧi 1 lҫn là chia đôi và làm tròn dưӟi vӟi sӕ có dҩu.
7) LӋnh ROL( Rotate All Bits to the Left)




                                                                             45
Chӭc năng: quay vòng sang trái các bit cӫa toán hҥng đích đi mӝt sӕ lҫn nào
đó (sӕ lҫn dӏch đưӧc cҩt trong thanh ghi CL). Trong mӛi lҫn quay giá trӏ bit cao
nhҩt vӯa chuyӇn vào thanh ghi cӡ CF đӗng thӡi chuyӇn vào bit thҩp nhҩt
     Cú pháp: ROL DST, CL
     (reg, mem)




    Tác đӝng đӃn cӡ: C, O.
    NӃu dӏch mӝt lҫn thì ta có thӇ viӃt trӵc tiӃp.
    VD:rol ax,1
8) LӋnh ROR
     Chӭc năng: quay vòng sang phҧi các bit cӫa toán hҥng đích đi mӝt sӕ lҫn
nào đó (sӕ lҫn dӏch đưӧc cҩt trong thanh ghi CL). Trong mӛi lҫn quay giá trӏ bit
thҩp LSB nhҩt vӯa chuyӇn vào thanh ghi cӡ CF đӗng thӡi chuyӇn vào bit cao
nhҩt MSB.
     Cú pháp: ROR DST, CL
    (reg, mem)



    Tác đӝng đӃn cӡ: C, O.
    NӃu dӏch mӝt lҫn thì ta có thӇ viӃt trӵc tiӃp.
    VD:ror ax,1

3.4 Các lӋnh thao tác vӟi dãy (chuӛi)
    Chú ý: ChӍ có 2 lӋnh trong nhóm này khi thӵc hiӋn làm thay đәi các bit cӡ.
1) LӋnh MOVSB/MOVSW (Move String Byte or String Word)
     Chӭc năng: ChuyӇn mӝt xâu ký tӵ theo tӯng byte(MOVSB) hay theo tӯng
tӯ (MOVSW) tӯ vùng nhӟ trӓ bӣi DS:SI sang vùng nhӟ trӓ bӣi ES:DI. Sau mӛi
lҫn dӏch chuyӇn thì giá trӏ cӫa SI, DI tӵ đӝng tăng lên 1 hoһc 2 khi cӡ hưӟng DF
= 0 hoһc giҧm đi 1 hoһc 2 khi DF = 1.
     Phҫn tӱ cӫa Chuӛi đíchĸ Phҫn tӱ cӫa Chuӛi gӕc
     Cú pháp: MOVSB hoһc MOVSW




                                                                             46
Chuҭn bӏ trưӟc ds:si con trӓ đӃn đҫu xâu SRC, es:di con trӓ đӃn đҫu xâu
DST
      LӋnh này không tác đӝng đӃn cӡ.
2) LӋnh LODSB/LODSW (Load String Byte or Word into AL/AX)
     Chӭc năng: ChuyӇn các kí tӵ theo tӯng byte (LODSB) hay theo tӯng tӯ
(LODSW) tӯ vùng nhӟ trӓ bӣi DS:SI vào AL/AX.
     Cú pháp: LODSB hoһc LODSW
     Chuҭn bӏ trưӟc ds:si con trӓ ӣ đҫu xâu, df = 0 hay df = 1.
     LӋnh này không tác đӝng đӃn cӡ.
3) LӋnh STOSB/STOSW (Store AL/AX in String Byte/Word)
     Chӭc năng: ChuyӇn các kí tӵ nҵm ӣ AL(STOSB) /AX (STOSW) vào vùng
nhӟ trӓ bӣi ES:DI.
     Cú pháp: STOSB hoһc STOSW hoһc STOS Chuӛi đích.
     Xác lұp trưӟc ES:DI trӓ đӃn đҫu vùng nhӟ, df = 0 hay df = 1.
     LӋnh này không tác đӝng đӃn cӡ.
     Nhұn xét
     1. movsb = lodsb + stosb
      2. movsw = lodsw + stosw
4) LӋnh CMPSB/CMPSW
     Chӭc năng: So sánh hai xâu kí tӵ theo tӯng byte (CMPSB) / theo tӯng tӯ
(CMPSW) giӳa hai vùng nhӟ trӓ bӣi DS:SI và ES:DI. LӋnh này chӍ tҥo cӡ,
không lưu lҥi kӃt quҧ so sánh, sau khi so sánh các toán hҥng không bӏ thay đәi.
     Cú pháp: CMPSB hoһc CMPSW hoһc STOS Chuӛi đích.
     Xác lұp trưӟc DS:SI trӓ đӃn đҫu xâu 1, ES:DI trӓ đӃn đҫu xâu 2, df = 0 hay
df = 1.
     Tác đӝng đӃn cӡ: ZF = 1 khi hai xâu bҵng nhau, ZF = 0 khi hai xâu khác
nhau.
5) TiӅn tӕ REP (Repeat String Instruction until CX = 0).
     Chӭc năng: Lһp đi lһp lai lӋnh làm viӋc vӟi xâu kí tӵ đҵng sau nó cho đӃn
khi cx = 0. Sau mӛi lҫn thӵc hiӋn cx tӵ đӝng giҧm đi 1
      Cú pháp: mov cx, sӕ lҫn


                                                                            47
rep lӋnh làm viӋc vӟi xâu ; rep movsb




    Thuұt toán
    1. DS:SI
    2. ES:DI
    3. D = 0
    4. CX = 5
    5. rep movsb; sau mӛi lҫn cx = cx ± 1 cho đӃn khi cx = 0.

3.5 Các lӋnh nhҧy ± ChuyӇn điӅu khiӇn
1) LӋnh Call
     Chӭc năng: Gӑi chương trình con
     Cú pháp




2) LӋnh RET
     Chӭc năng: quay vӅ chương trình đã gӑi chương trình con
     Cú pháp: RET (nҵm ӣ cuӕi chương trình con)
3) LӋnh INT
     Chӭc năng: Kích hoҥt mӝt ngҳt (chuyӇn sang chҥy chương trình con phөc
vө ngҳt) (Ngҳt mӅm).
     Cú pháp: int n (sӕ ngҳt viӃt theo sӕ hexa)
     Ví du: int 21h = int 33
     Các ngҳt hay dùng hӛ trӧ cho lұp trình Assembler
    y Hàm 1: Chӡ 1 kí tӵ
    mov ah,1 ; gán ah = 1 al chӭa mã ASCII
    ; al = 0 khi kí tӵ gõ vào là các phím chӭc năng.
    int 21h
    y Hàm 2: HiӋn 1 ký tӵ lên màn hình tӯ vӏ trí con trӓ đang đӭng.


                                                                       48
Cách 1:
    mov al, mã ASCII
    mov ah,0eh
    int 10h
    Cách 2:
    mov dl, mã ASCII
    ; dl = mã ASCII cӫa kí tӵ cҫn hiӇn thӏ
    mov ah,2
    int 21h
    y Hàm 3: HiӋn xâu kí tӵ kӃt thúc µ$¶ lên màn hình.
    lea dx, tên biӃn xâu
    ; mov dx,offset tên biӃn xâu
    mov ah,9
    int 21h
    y Hàm 4: Trӣ vӅ DOS
    mov ah,4ch
    int 21h
4) LӋnh IRET
      Chӭc năng: quay vӅ chương trình đã kích hoҥt nó tӯ chương trình con phөc
ngҳt.
      Cú pháp: IRET
      - LӋnh JMP (go to)
    Chӭc năng: nhҧy không điӅu kiӋn
    Cú pháp:




    Chú ý: Bưӟc nhҧy cӫa lӋnh jump < 64k
5) LӋnh nhҧy có điӅu kiӋn
Vӟi sӕ không có dҩu       Vӟi sӕ có dҩu               Nhҧy theo trҥng thái các
(Below/above)             (Less/ greater)             bit cӡ
Cmp DST, SRC                             Cmp DST, SRC
Jb/jnae Nhãn KhiDST dưӟi Jl/jnge Nhãn    Khi          jc Nhãn     Khi
Đӏa chӍ      SRC         Đӏa chӍ         DST<SRC      Đӏa chӍ     CF=1
Jbe/jna Nhãn Khi    DST Jle/jng Nhãn     Khi          jnc Nhãn    Khi
Đӏa chӍ      dưӟi   SRC Đӏa chӍ          DST”SRC      Đӏa chӍ     CF=0
             hoһc =
Je Nhãn      Khi         Je Nhãn         Khi          jz Nhãn     Khi



                                                                           49
Đӏa chӍ         DST= SRC       Đӏa chӍ        DST= SRC    Đӏa chӍ    ZF=1
Jne Nhãn        Khi            Jne Nhãn       Khi         jnz Nhãn   Khi
Đӏa chӍ         DST SRC       Đӏa chӍ        DST SRC    Đӏa chӍ    ZF=0
Ja/jnbe Nhãn    Khi DST trên   Jg/jnle Nhãn   Khi         js Nhãn    Khi
Đӏa chӍ         SRC            Đӏa chӍ        DST > SRC   Đӏa chӍ    SF=1
Jae/jnb Nhãn    Khi DST trên   Jge/jnl Nhãn   Khi         jns Nhãn   Khi
Đӏa chӍ         /=SRC          Đӏa chӍ        DST •SRC    Đӏa chӍ    SF=0
       Chú ý: Bưӟc nhҧy các lӋnh nhҧy có điӅu kiӋn phҧi nhӓ hơn hoһc bҵng 128
byte
6) LӋnh LOOP (for cӫa ASM)
     Chӭc năng: lһp đi lһp lҥi khӕi lӋnh ASM nҵm giӳa nhãn và loop cho đӃn khi
cx = 0. Mӛi khi thӵc hiӋn mӝt vòng lһp giá trӏ cӫa CX giҧm đi 1.
       Cú pháp:
       mov cx, sӕ lҫn lһp; sӕ lҫn lһp • 1
       Nhan:
           Khӕi lӋnh ASM
       Loop Nhan

3.6 Các lӋnh thao tác vӟi cӡ và điӅu khiӇn bӝ
1) LӋnh CLC (Clear CF)
     Chӭc năng: Xoá giá trӏ cӡ CF vӅ 0, CF = 0
       Cú pháp: CLC
       Cӡ C = 0
2) LӋnh STC
     Chӭc năng: Đưa giá trӏ cӡ CF lên 1, CF = 1
     Cú pháp: STC
     Cӡ C = 1
3) LӋnh CMC
     Chӭc năng: Đҧo giá trӏ hiӋn thӡi cӫa cӡ CF.
     Cú pháp: CMC
     Tác đӝng đӅn cӡ C.
4) LӋnh CLI
     Chӭc năng: Xoá giá trӏ cӫa cӡ IF vӅ 0(IF = 0). Cҩm toán bӝ các ngҳt cӭng
trӯ ngҳt MNI.
     Cú pháp: CLI
     Cӡ IF = 0.
5) LӋnh STI
     Chӭc năng: Đưa giá trӏ cӫa cӡ IF lên1 (IF = 1). Cho phép ngҳt cӭng.
       Cú pháp: STI


                                                                            50
Cӡ IF = 1.
6) LӋnh CLD
     Chӭc năng: Xoá giá trӏ cӫa cӡ DF vӅ 0 (DF = 0).
     Cú pháp: CLD
     Cӡ DF = 0, dӵng cӡ.
7) LӋnh STD
     Chӭc năng: Đưa giá trӏ cӫa cӡ DF lên1 (DF = 1).
     Cú pháp: STD
     Cӡ DF = 1.
8) LӋnh HLT
     Chӭc năng: dӯng máy
     Cú pháp: HLT
9) LӋnh NOP
     Chӭc năng: lӋnh này không thӵc hiӋn gì cҧ
     Cú pháp: NOP (4ȝs)
     Ý nghĩa:
    Tҥo trӉ (delay)




    Tҥo vòng chӡ vô tұn đӇ chӡ ngҳt.
    L1: nop
    jmp L1




                                                       51
Chương 4 Chương trình con và chương trình đa tӋp
4.1 Thӫ tөc ± Chương trình con
    Trong các chương trình cӥ lӟn, viӋc module hóa đӇ cho chương trình có cҩu
trúc sáng sӫa, dӉ debug và tiӃt kiӋm thӡi gian viӃt mã là mӝt viӋc hӃt sӭc quan
trӑng. ĐӇ có thӇ module hóa đưӧc chương trình chúng ta cҫn phҧi sӱ dөng mӝt
trong các công cө rҩt hӳu hiӋu đó là thӫ tөc ± chương trình con. Chương trình
con là mӝt đoҥn các mã lӋnh đưӧc gӝp lҥi và đưӧc đһt tên, thông qua tên (bҵng
cách gӑi tên), chúng ta có thӇ sӱ dөng lҥi mӝt đoҥn mã lӋnh ӣ bҩt cӭ nơi nào ta
cҫn trong chương trình thay vì phҧi viӃt lҥi hoàn toàn đoҥn mã lӋnh đó.

4.1.1 Cơ chӃ làm viӋc cӫa chương trình con
     Nói chung cơ chӃ làm viӋc cӫa chương trình con trong ASM không khác gì
nhiӅu so vӟi các ngôn ngӳ bұc cao khác.
     Cơ chӃ có 5 bưӟc :
     - Bưӟc 1: Tham sӕ thӵc đưa vào stack
     - Bưӟc 2: Đӏa chӍ lӋnh tiӃp theo đưa vào stack
     - Bưӟc 3: HӋ điӅu hành biӃt đưӧc đӏa chӍ đҫu cӫa chương trình con. Do vұy
hӋ điӅu hành đưa đӏa chӍ đҫu cӫa chương trình con vào CS:IP rӁ nhánh vào
chương trình con.
     - Bưӟc 4: Thӵc hiӋn chương trình con cho đӃn khi gһp return thì vào stack
lҩy đӏa chӍ lӋnh tiӃp theo (đã cҩt ӣ bưӟc 2 đӇ đưa vào CS:IP) và quay vӅ chương
trình đã gӑi nó.
     - Bưӟc 5: tiӃp tөc chương trình đang thӵc hiӋn dӣ.




4.1.2 Cҩu trúc cӫa chương trình con
    Tên chương trình con PROC [near/far]
       Bҧo vӋ các thanh ghi mà thân chương trình con phá vӥ.
           Các lӋnh ASM cӫa thân chương trình con.
       Hӗi phөc các thanh ghi mà thân chương trình con đã phá vӥ.
       RET


                                                                            52
Tên chương trình con ENDP
    Nhұn xét:
    1. Chương trình con thuҫn tuý ASM không có tham sӕ.
    2. Vҩn đӅ near/ far
    - Chương trình con là near khi mã máy cӫa chương trình con và mã máy cӫa
chương trình chính là cùng nҵm trong 1 segment, đӏa chӍ cӫa chương trình con và
chương trình chính chӍ khác nhau phҫn đӏa chӍ offset. Cho nên đӏa chӍ lӋnh tiӃp
theo cҩt váo stack chӍ cҫn 2 byte offset.
     - Chương trình con là far khi mã máy cӫa chương trình con và mã máy cӫa
chương trình chính nҵm trên các segment khác nhau, đӏa chӍ cӫa chương trình
con và chương trình chính khác nhau cҧ vӅ phҫn đӏa chӍ segment. Cho nên đӏachӍ
lӋnh tiӃp theo cҩt vào stack phҧi cҫn 4 byte offset.
     Default:
     - Vӟi chương trình đưӧc khai báo directive dҥng đơn giҧn thì directive
MODEL sӁ cho biӃt chương trình con là near hay far
     NӃu .MODEL tiny/small/compact thì chương trình con là NEAR(mã máy<
64k)
     NӃu .MODEL medium/large/huge thì chương trình con là FAR(mã
máy>64k
     - Vӟi chương trình con đưӧc viӃt theo directive dҥng chuҭn thì mһc đӏnh là
near. Còn muӕn chương trình con là far thì phҧi viӃt far khi viӃt chương trình
con.

4.1.3 Vҩn đӅ chuyӇn giao tham sӕ
     Trong chương trình con cӫa hӧp ngӳ không có tham sӕ hình thӭc vì vұy mà
viӋc trao đәi dӳ liӋu giӳa chương trình con và chương trình chính gӑi nó đưӧc
thӵc hiӋn thông qua 3 cách sau:
    y ChuyӇn tham sӕ thông qua các thanh ghi: Cách này đơn giҧn và dӉ viӃt
      thưӡng đưӧc sӱ dөng trong các chương trình thuҫn túy ASM. Vӟi cách
      này ta chӍ cҫn đһt mӝt giá trӏ vào thanh ghi nào đó trong chương trình
      chính sau đó gӑi chương trình con và chương trình con sӁ sӱ dөng đưӧc
      giá trӏ trong thanh ghi đó. Nó giӕng như ta đưa các chӭc năng con vào
      thanh ghi AH trưӟc khi gӑi ngҳt cӫa hӋ thӕng, đó cũng là mӝt cách
      truyӅn tham sӕ cho chương trình con thông qua thanh ghi.




                                                                            53
y ChuyӇn tham sӕ thông qua các biӃn ngoài: BiӃn khai báo toàn cөc đưӧc
       sӱ dөng trong toàn chương trình, cҧ chương trình chính và chương trình
       con, do vұy ta có thӇ dùng nó đӇ chuyӇn tham sӕ.
     y ChuyӇn tham sӕ thông qua ngăn xӃp: Phương pháp này cҫn lưu thӭ tӵ
       sҳp xӃp trong ngăn xӃp đӇ truy cұp các tham sӕ.

4.1.4 Vҩn đӅ bҧo vӋ các thanh ghi
     ViӋc bҧo vӋ các thanh ghi trong quá trình gӑi các chương trình con là mӝt
vҩn đӅ rҩt quan trӑng trong lұp trình ASM vì chương trình viӃt bҵng ASM rҩt
hay dùng các toán hҥng là các thanh ghi. Do vұy trong chương trình con đôi khi
có thӇ làm thay đәi giá trӏ cӫa mӝt thanh ghi nào đó làm ҧnh hưӣng tӟi kӃt quҧ
thӵc hiӋn cӫa chương trình chính. Có hai phương pháp thưӡng dùng là:
     y Dùng lӋnh Push đӇ cҩt thanh ghi vào ngăn xӃp ӣ đҫu chương trình con
       và cuӕi chương trình con ta dùng lӋnh POP đӇ lҩy lҥi các giá trӏ cӫa các
       thanh ghi.
     y Dùng theo quy ưӟc: Nhӳng thanh ghi nào dùng trong chương trình chính
       thì không dùng trong chương trình con nӳa. Tuy nhiên cách này không
       hiӋu quҧ lҳm và ít dùng vì có nhӳng thanh ghi ta buӝc phҧi sӱ dөng mà
        không thӇ thay thӃ đưӧc.

4.1.5. Mӝt sӕ ví dө
     Ví dө 1: ViӃt chương trình con tính a^b.
     .model small                                 add ax,tong
     .data                                        mov ah,4ch
      tong dw 0                                    int 21h
     .stack 100h                                hammu proc
     .code                                        push bx
       begin:                                     push cx
         mov ax,@data                             mov cx,bx
         mov ds, ax                               mov bx,ax
         mov ax, 2                                mov ax,1
        mov bx, 3                                 l1:
        call hammu                                  mul bx
        mov tong,ax                               loop l1
        mov ax, 3                                 pop cx
        call hammu                                pop bx


                                                                            54
ret                                      end begin
     hammu endp
       Trong chương trình này ta sӱ dөng thanh ghi ax là tham sӕ hình thӭc đӇ
truyӅn cho chương trình con. Sau khi gӑi hammu lҫn 1, kӃt quҧ thӵc hiӋn cӫa
chương trình con đưӧc lưu vào thanh ghi ax, vì đưӧc dùng làm tham sӕ nên ax sӁ
bӏ thay đәi khi ta gӑi hammu lҫn 2, vì vұy đӇ bҧo vӋ kӃt quҧ ta lưu kӃt quҧ vào
mӝt biӃn tәng.
     Ví dө 2: ViӃt chương trình con dùng đӇ kiӇm tra mӝt sӕ là chҹn hay là lҿ:
     .model small                                 pop bx
     .code                                        ret
       org 100h                                hammu endp
       begin:                                  chanle proc
       jmp entry                                  push ax
        c db "chan$"                              push bx
        l db "le$"                                push cx
        tong dw 0                                 mov bl,2
       entry:                                     div bl
       mov ax, @data                              cmp ah,0
       mov ds, ax                                 je chan
       mov ax, 2                                   lea dx,l
       call chanle                                 mov ah,9
       mov ax, 3                                   int 21h
       call chanle                                jmp kt
       int 20h                                    chan:
    hammu proc                                     lea dx,c
      push bx                                      mov ah,9
      push cx                                      int 21h
       mov cx,bx                                kt:
       mov bx,ax                                pop cx
       mov ax,1                                 pop bx
       l1:                                      pop ax
         mul bx                                 ret
       loop l1                                chanle endp
       pop cx                                 end begin
       Trong mӝt chương trình có thӇ có nhiӅu hơn mӝt chương trình con. Như
bҥn thҩy ӣ chương trình trên.


                                                                            55
Ví dө 3: Hãy viӃt chương trình con ASM cho phép nhұn mӝt sӕ nguyên (-
32768 ~ 32767) tӯ bàn phím kӃt thúc nhұn mӝt sӕ nguyên bҵng phím Enter (13 =
0dh). KӃt quҧ nҵm trong thanh ghi ax. Chú ý không cho phép đánh sai và sӱa.
     a) Nhұn sӕ nguyên dương
     - Dùng hàm nhұn kí tӵ
    mov ah, 1
    int 21h
    Suy ra al chӳa mã ASCII cӫa kí tӵ.
    al ± 30h: thành mã ASCII chuyӇn thành sӕ
    - Sӕ vӯa đưa vào sӁ cӝng phҫn sӕ đã cҩt vào trưӟc *10
    b) Nhұn mӝt sӕ nguyên âm
    - Có 1 biӃn cӡ dҩu: 0 là sӕ dương, 1 là sӕ âm.
    NӃu phát hiӋn kí tӵ đҫu là dҩu âm thì biӃn cӡ dҩu sӁ bҵng 1.
    Nhұn mӝt sӕ nguyên dương sau đó hӓi biӃn cӡ dҩu. NӃu cӡ dҩu = 1 thì
chuyӇn sang sӕ bù 2 đӇ đәi dҩu.
    vsn proc                                        sub al,30h
       push bx                                      xchg ax,cx
       push cx                                      mul bx
       push dx                                      add cx,ax
       push si                                        jmp l1
       mov bx,10                                l3:
       xor cx,cx                                      cmp si,0
       mov si,cx                                      je l4
       l1:                                            neg cx
         mov ah,1                               l4:
         int 21h                                 mov ax,cx
         cmp al,13                                pop si
         je l3                                  pop dx
         cmp al,'-'                             pop cx
         jne l2                                 pop bx
         inc si                                 ret
         jmp l1                                vsn endp
       l2:
         xor ah,ah
     Ví dө 4: ViӃt chương trình con hiӋn nӝi dung có trong AX ra ngoài màn
hình dҥng cơ sӕ 10.


                                                                         56
Thuұt toán:
    a) AX chӭa sӕ nguyên dương
    Thuұt toán:




    vòng loop
    X: pop ax
    mov ah, 0ch
    int 10h
    loop X
    b) AX chӭa sӕ âm
    KiӇm tra hiӋn AX ” 0
    NӃu AX ” 0 hiӋn dҩu ra màn hình sau đó đәi dҩu AX rӗi hiӋn như mӝt sӕ
nguyên dương sau dҩu trӯ.
    Chương trình
    hsn proc                                   neg ax
      push ax                                  push ax
      push bx                                  mov al,'-'
      push cx                                  mov ah,0eh
      push dx                                  int 10h
      mov bx,10                                pop ax
      xor cx,cx                               l2:
      l1:                                      xor dx,dx
        and ax,ax                              div bx
        jns l2                                 inc cx


                                                                       57
push dx                                    loop l3
        cmp ax,0                                  pop dx
        jne l2                                    pop cx
       l3:                                        pop bx
        pop ax                                    pop ax
        add ax,30h                                ret
        mov ah,0eh                               hsn endp
        int 10h                                 end begin

4.2 Chương trình đa tӋp
     Trong các mөc trưӟc chúng ta chӍ biӃt cách viӃt ra mӝt chương trình cӥ nhӓ
trên mӝt file (tӋp) .asm. Chương trình trên mӝt tӋp ngҳn, đơn giҧn và dӉ viӃt.
Tuy nhiên đӕi vӟi chương trình cӥ vӯa và lӟn tӕt nhҩt là chúng ta chia thành
nhiӅu tӋp (module) khi viӃt chương trình, sau đó dӏch và liên kӃt chúng lҥi vӟi
nhau. Chương trình viӃt trên nhiӅu tӋp có thuұn lӧi như sau:
    y Cho phép nhiӅu ngưӡi dùng tham gia vào giҧi quyӃt vҩn đӅ
    y ViӋc kiӇm soát lӛi và sӱa lӛi trên tӯng module riêng biӋt nên có nhiӅu
      thuұn lӧi hơn. Vì mӛi module thưӡng giҧi quyӃt mӝt vҩn đӅ nhӓ riêng.

4.2.1 LӋnh điӅu khiӇn PUBLIC
     Chͱc năng: báo cho chương trình dӏch ASM biӃt module (tӋp) này cho phép
các tӋp khác đưӧc dùng nhӳng nhãn nào mà không cҫn xác lұp lҥi.
    Cú pháp:
    PUBLIC Tên nhãn
     Xác lұp nhãn
    y Trưӡng hӧp nhãn là tên biӃn :
    .DATA
      PUBLIC Tên biӃn
        Khai báo biӃn
    Ví dө:
    .DATA
      PUBLIC x,y
       x db ?
       y dw ?
    y Trưӡng hӧp nhãn là tên chương trình con :
    .CODE PUBLIC Tên chương trình con


                                                                            58
Tên chương trình con PROC
          RET
        Tên chương trình con ENDP

4.2.2 LӋnh điӅu khiӇn EXTERN
    Chͱc năng: báo cho chương trình dӏch ASM biӃt tӋp này xin phép dùng các
nhãn mà các modul khác đã xác lұp và cho phép.
    Cú pháp:
    EXTRN Tên nhãn: KiӇu
    y Trưӡng hӧp vӟi nhãn là biӃn nhӟ :
    .DATA
      EXTRN Tên biӃn: KiӇu         PUBLIC
                        BYTE db
                          WORD dw
                          DWORD dd
    Ví dө:
    .DATA EXTRN X:BYTE, Y:WORD
    y Trưӡng hӧp nhãn là tên chương trình con:
    .CODE
      EXTRN Tên chương trình con:PROC

4.2.3 LӋnh điӅu khiӇn GLOBAL
     LӋnh điӅu khiӇn GLOBAL có thӇ thay thӃ cҧ hai lӋnh PUBLIC và EXTRN
ӣ trên khi ta dùng chương tình dӏch TASM. NӃu chúng ta khai báo GLOBAL cho
các nhãn có kèm theo khai báo dҥng nhãn thì GLOBAL khi đó thay thӃ cho
PUBLIC, còn khi dùng GLOBAL khai báo nhãn đi sau có kèm theo kiӇu nhãn thì
lúc đó GLOBAL thay thӃ co EXTRN.
     Ví dө GLOBAL thay thӃ cho PUBLIC:
    .DATA
      GLOBAL n,m,a
      N EQU 10
      A DB n DUP(?)
      M DW 15
    Ví dө GLOBAL thay thӃ cho EXTRN:
    .DATA
    GLOBAL X:BYTE, Y: WORD


                                                                        59
.CODE
     GLOBAL NEARPROC:NEAR
     Call nearpro
     Chú ý: Sau khi viӃt chương trình cho các module riêng biӋt bây giӡ ta phҧi
dӏch và liên kӃt các module lҥi vӟi nhau. Quá trình liên kӃt như sau:
    y Dùng chương trình dӏch đӇ dӏch các module (file.ASM) thành các file
      .OBJ
    y Dùng chương trình liên kӃt LINK hay TLINK đӇ liên kӃt các .OBJ lҥi
      vӟi nhau theo cú pháp:
         TLINK module1.obj+module2.obj+«+modulen.obj
     Như vұy nó sӁ tҥo ra file thi hành đưӧc có tên là module1.exe. NӃu muӕn
dӏch ra file .com thì ta thêm tham sӕ /t như bình thưӡng.
     Ví dө: viӃt chương trình tính n!, trong đó module chính khai báo mӝt biӃn
n, gӑi chương trình con cho nhұp vào mӝt sӕ tӯ module thӭ 2, gӑi chương trình
con tính giai thӯa tӯ module thӭ 3, và cuӕi cùng gӑi mӝt chương trình con hiӋn
kӃt quҧ tӯ module thӭ 2.
    Module 2: module hiӋn và nhұp mӝt sӕ
    .model small                                   cmp al,'-'
    .stack 100h                                    jne vsn2
    .data                                          inc si
    .code                                          jmp vsn1
     begin:                                        vsn2:
      public vsn,hsn                               xor ah,ah
      vsn proc                                     sub al,30h
       push bx                                     xchg ax,cx
       push cx                                     mul bx
       push dx                                     add cx,ax
       push si                                     jmp vsn1
        mov bx,10                                  vsn3:
        xor cx,cx                                  cmp si,0
        mov si,cx                                  je vsn4
        vsn1:                                      neg cx
        mov ah,1                                   vsn4:
        int 21h                                    mov ax,cx
        cmp al,13                                 pop si
        je vsn3                                   pop dx

                                                                            60
pop cx                                      hsn2:
       pop bx                                       xor dx,dx
       ret                                          div bx
      vsn endp                                      inc cx
      hsn proc                                      push dx
       push ax                                      cmp ax,0
       push bx                                      jne hsn2
       push cx                                     hsn3:
       push dx                                      pop ax
        mov bx,10                                   add ax,30h
        xor cx,cx                                   mov ah,0eh
        hsn1:                                       int 10h
        and ax,ax                                  loop hsn3
        jns hsn2                                  pop dx
        neg ax                                    pop cx
        push ax                                   pop bx
        mov al,'-'                                pop ax
        mov ah,0eh                                ret
        int 10h                                  hsn endp
         pop ax                                end begin
     Module 3: Có chương trình con tính giai thӯa cӫa mӝt sӕ, vӟi sӕ cҫn tính là
biӃn public n cӫa module 1. Sau khi tính toán, module 3 lưu kӃt quҧ vào mӝt
biӃn public là kq, sau này module 1 (module chính) sӁ dùng biӃn này đӇ lҩy vӅ
kӃt quҧ.
     .model small                                public gth
     .stack 100h                                 gth proc
     .data                                         push ax
     extrn n:word                                  push bx
     public kq                                     push cx
      kq dw ?                                      push dx
     .code                                         mov cx,n
      begin:                                       mov ax,1
       mov ax,@data                                l1:
       mov ds,ax                                     mul cx
       mov ah,4ch                                   loop l1
       int 21h                                     mov kq,ax


                                                                             61
pop dx                                     ret
      pop cx                                    gth endp
      pop bx                                   end begin
      pop ax
    Module 1: Khai báo biӃn public n (sӕ cҫn tính giai thӯa), gӑi chương trình
con nhұp sӕ n vào tӯ bàn phím (chương trình con cӫa module 2), gӑi chương
trình con tính giai thӯa cӫa n (chương trình con cӫa module 3), hiӋn kӃt quҧ
thông qua biӃn public kq cӫa module 3(module 2).
     .model small                                ,hsn:near
     .stack 100h                                ,gth:near
     .data                                       call vsn
      PUBLIC n                                   mov n,ax
     n dw ?                                       call gth
     EXTRN kq:word                                mov ax,kq
     .code                                        call hsn
      begin:                                      mov ah,4ch
       mov ax,@data                               int 21h
       mov ds,ax                                 end begin
       extrn vsn:near

4.2.4. TӋp INCLUDE và cách dùng
     Như ӣ trên ta đã đӅ cұp đӃn chương tình lӟn có thӇ chia thành nhiӅu module
và ta phҧi dӏch tҩt cҧ các module đó mӛi khi có thay đәi. Tuy nhiên có nhӳng lúc
ta thay đәi các mudule mà không phҧi dӏch lҥi các module đó mà chӍ đӏnh mӝt
module chính mà thôi. ĐӇ giҧi quyӃt vҩn đӅ đó chương trình dӏch ASM có mӝt
lӋnh là INCLUDE.

4.2.4.1. Cú pháp và cơ chӃ tiӃn hành dӏch khi gӑi tӋp INCLUDE
     Cú pháp: INCLUDE tên tӋp
     Trong đó tên tӋp ta chӍ ra mӝt tӋp chӭa mӝt khӕi lӋnh ASM mà ta muӕn nӕi
nó vào vӏ trí mà có lӋnh INCLUDE đӭng.
     LӋnh này có tác dөng copy toàn bӝ nӝi dung cӫa tӋp đưӧc chӍ ra sau đó đһt
nó vào vӏ trí cӫa lӋnh INCLUDE.
     Ví dө:
    Mӝt tӋp có tên là ASM có tên là main.asm :
    «



                                                                             62
.CODE
     «
       Mov dx, offset tb1
       Include hiens
     «
       Int 20h
     Trong đó tӋp hiens có nӝi dung như sau:
     Mov ah,09h
     Int 21h
     Thì khi dӏch tӋp main.asm nó sӁ có kӃt quҧ như sau:
     «
       .CODE
      Mov dx, offset tb1
      Mov ah,09h
      Int 21h
     «
      Int 20h

4.2.4.2. Vҩn đӅ tìm tӋp INCLUDE
     Vҩn đӅ là chương trình dӏch cӫa ASM sӁ tìm lӋnh INCLUDE ӣ đâu:
     y NӃu trong tên tӋp có chӍ rõ đưӡng dүn thì chương trình dӏch sӁ tìm tӋp ӣ
       thư mөc đó
     y NӃu trong tên tӋp không chӍ ra đưӡng dүn mà chӍ có tên tӋp thì chương
       trình dӏch sӁ tìm tӋp trong thư mөc hiӋn hành
     y NӃu không tìm ra tӋp thì chương trình dӏch sӁ báo lӛi
4.2.4.2. Ví dө
     Mӝt chương trình hoàn chӍnh phҧi cho phép ngưӡi dùng nhұp dӳ liӋu và và
hiӇn thӏ đưӧc kӃt quҧ thӵc thi cӫa chương trình. Ta đã có các chương trình con
đӇ thӵc hiӋn hai công viӋc nhұp xuҩt đó, tuy nhiên, trưӟc kia khi chưa sӱ dөng
chương trình đa tӋp, mӛi lҫn viӃt mӝt chương trình mӟi chúng ta lҥi phҧi viӃt lҥi
các chương trình con nhұp/xuҩt này.
     Bây giӡ vӟi INCLUDE, chúng ta sӁ không phҧi viӃt lҥi các chương trình
con này nӳa mà chӍ cҫn viӃt nó trên mӝt file và dùng lӋnh INCLUDE đӇ thêm nó
vào chương trình thay vì phҧi viӃt lҥi.
    Ví dө dưӟi đây mô tҧ cách dùng INCLUDE đӇ nҥp các chương trình con
nhұp/xuҩt đӇ giҧi quyӃt bài toán ³tính t͝ng hai s͙ đưͫc nh̵p vào tͳ bàn phím´.

                                                                              63
Ta viӃt tӋp lib.asm, chӭa các chương trình con nhұp xuҩt:
vsn proc                                     vsn endp
  push bx                                    hsn proc
  push cx                                     push ax
  push dx                                     push bx
  push si                                     push cx
   mov bx,10                                  push dx
   xor cx,cx                                   mov bx,10
   mov si,cx                                   xor cx,cx
   vsn1:                                       hsn1:
   mov ah,1                                     and ax,ax
   int 21h                                      jns hsn2
   cmp al,13                                   neg ax
   je vsn3                                     push ax
   cmp al,'-'                                  mov al,'-'
   jne vsn2                                    mov ah,0eh
   inc si                                      int 10h
   jmp vsn1                                    pop ax
   vsn2:                                      hsn2:
   xor ah,ah                                   xor dx,dx
   sub al,30h                                  div bx
   xchg ax,cx                                  inc cx
   mul bx                                      push dx
   add cx,ax                                   cmp ax,0
   jmp vsn1                                    jne hsn2
   vsn3:                                      hsn3:
   cmp si,0                                    pop ax
   je vsn4                                      add ax,30h
   neg cx                                       mov ah,0eh
   vsn4:                                        int 10h
   mov ax,cx                                   loop hsn3
  pop si                                      pop dx
  pop dx                                      pop cx
  pop cx                                      pop bx
  pop bx                                      pop ax
  ret                                         ret


                                                             64
hsn endp
    ViӃt chương trình tính tәng hai sӕ đưӧc nhұp vào tӯ bàn phím:
    .model small
    .stack 100h
    .code
     begin:
      call vsn
      mov bx,ax
      call vsn
      add ax,bx
      call hsn
      mov ah,4ch
        int 21h
        include lib.asm
       end begin
     Tӯ bây giӡ, đӇ nhұp xuҩt đưӧc sӕ, bҥn chӍ cҫn include lib.asm vào chương
trình.

4.2.5 MACRO và vҩn đӅ liên quan

4.2.5.1. Chӭc năng
     Macro thӵc chҩt rҩt đơn giҧn, nӃu chúng ta gán mӝt tên thay cho mӝt khӕi
lӋnh và sau đó khi chương trình ASM gһp tên này ӣ đâu trong chương trình thì
khӕi lӋnh đó sӁ đưӧc dӏch và đһt khӕi mã lӋnh đó vào vӏ trí mà chương trình gӑi
tên Macro.
     Có thӇ nói MACRO gҫn giӕng vӟi lӋnh INCLUDE, nó dùng mӝt tên thay
cho mӝt khӕi mã lӋnh và khi chương trình dӏch ASM gһp tên này ӣ đâu thì nó
dӏch và đһt khӕi lӋnh vào đó.
     Sӵ khác nhau giӳa MACRO và INCLUDE là:
    y MACRO có thӇ chuyӇn giao tham sӕ
    y MACRO có thӇ chӭa các nhãn cөc bӝ
    y MACRO tiӃn hành dӏch nhanh hơn.
    y MACRO có thӇ sӱ dөng các lӋnh điӅu khiӇn điӅu kiӋn khi dӏch

4.2.5.1. Khai báo (xác lұp) MACRO
    Cú pháp:



                                                                            65
Tên Macro Macro [đӕi]
     Bҧo vӋ các thanh ghi mà thân Macro phá vӥ
       Các lӋnh ASM trong thân Macro
     Hӗi phөc các thanh ghi mà thân Macro đã phá vӥ
    ENDM
     Ví dө: Hãy khai báo 1 Macro tҥo 1 lӋnh mӟi cho phép xoá toàn bӝ màn hình
     Cơ chӃ màn hình ӣ chӃ đӝ text, mӛi lҫn đһt mode cho màn hình thì màn
hình sӁ bӏ xoá và con trӓ đӭng ӣ góc trên bên trái.
     Set mode:
     mov al, sӕ mode
     mov ah,0
     int 10h
    Get mode:
    mov ah, 0fh
    int 10h
    MACRO sӁ đưӧc xây dӵng như sau:
    Clrscr MACRO
      push ax
      mov ah,0fh; get mode
     int 10h
     mov ah,0
     int 10h; set mode
     pop ax
    ENDM
    Ví dө 2: Khai báo 1 Macro cho phép hiӋn 1 xâu lên màn hình
    Hienstring MACRO xau
     push ax dx
     lea dx, xau
     mov ah,9
     int 21h
     pop dx ax
    ENDM
4.2.5.2. Cách dùng MACRO đã đưӧc xác lұp
     ViӋc sӱ dөng MACRO đã đưӧc khai báo chӍ đơn giҧn là gӑi tên MACRO.
Ví dө muӕn gӑi MACRO xóa màn hình ta chӍ cҫn gӛ lӋnh:



                                                                          66
Clrscr
     MACRO và chương trình con khá giӕng nhau, tuy nhiên MACRO đưӧc
khai bao ӣ đҫu chương trình chính, trong khi đó chương trình con thưӡng đưӧc
khai báo ӣ cuӕi chương trình chính.
     MACRO thưӡng đưӧc sӱ dөng vì các nguyên nhân sau:
     y Thӵc hiӋn MACRO nhanh hơn là dùng chương trình con vì tránh đưӧc
       hai lӋnh là CALL và RET.
     y MACRO linh hoҥt hơn chương trình con vì nó có thӇ sӱ dөng các lӋnh
       điӅu khiӇn điӅu kiӋn dӏch và sӵ trao đәi thông sӕ hình thӭc, chúng ta có
        thӇ tҥo ra các mã lӋnh khác nhau nhҵm thӵc hiӋn các công viӋc gҫn
        giӕng nhau. Mà điӅu này thì chương trình con không làm đưӧc
     y MACRO có thӇ lӗng nhau
     Chú ý:
     Cơ chӃ cӫa chương trình dӏch khi gһp lӋnh mӟi
     Clrscr
     Hienstring M1
     - ĐiӅu gì xҭy ra nӃu có lӋnh nhҧy trong Macro?
     Phҧi dùng Directive LOCAL
     Ví dө:
     X Macro
     LOCAL L1
     L1:
     LOOP L1
     ENDM
4.2.5.3. Ví dө
     Phҫn trên bҥn đã tҥo ra lib.asm đӇ sӱ dөng chương trình con nhұp xuҩt
trong các chương trình ASM bҥn tҥo ra. Tuy nhiên, mӝt chương trình không thӇ
là hoàn thiӋn nӃu thiӃu đi các chӍ thӏ cӫa chương trình, ví dө ³mӡi bҥn nhұp´,
hay ³kӃt quҧ là´. ĐӇ thay vì viӋc phҧi viӃt lҥi macro hiens, chúng ta sӁ tҥo ra file
lib2.asm chӭa macro này, và mӛi khi cҫn dùng, bҥn chӍ cҫn include lib2.asm.
Dưӟi đây chúng ta sӁ cùng làm lҥi ví dө vӅ tính tәng hai sӕ:
     Tҥo ra lib2.asm có nӝi dung như sau:
     hiens macro s
        push ax
        push dx


                                                                                 67
lea dx,s
        mov ah,9
        int 21h
       pop dx
       pop ax
     endm
     ViӃt chương trình tính tәng 2 sӕ nhұp vào tӯ bàn phím sӱ dөng lib.asm và
lib2.asm:
     .model small
     .stack 100h
     .data
      x1 db 10,"moi nhap: $"
     x2 db 10,"ket qua : $"
    .code
    include lib2.asm
     begin:
      mov ax,@data
      mov ds,ax
      ;hien xau moi nhap
     hiens x1
     ;goi ctr nhap
     call vsn
     ;luu lai gtri nhap
     ;trong thanh ghi bx
     mov bx,ax
     ;hien xau moi nhap
     ;lan 2
     hiens x1
     ;goi ctr nhap
     call vsn
     ;ket qua nhap da
     ;nam trong ax
     ;ta tien hanh cong
     add ax,bx
     ;hien thi ket qua
     hiens x2


                                                                          68
call hsn
 mov ah,4ch
 int 21h
 include lib.asm
end begin




                   69
Chương 5: Các thao tác vӟi tӋp

5.1 Thҿ File (File Handles)
5.1.1 Khӕi điӅu khiӇn file ± FCB (File Control Blocks)
     FCBs giӳ các thông tin vӅ file như tên ә đĩa chӭa file, tên file, kích thưӟc
file,« Tuy nhiên, FCBs hҥn chӃ đӝ dài tӕi đa cӫa tên file là 11 kí tӵ, chính vì
vұy mà khi dùng FCBs đӇ thao tác vӟi file ta chӍ có thӇ thao tác vӟi file ӣ thư
mөc hiӋn thӡi. Tuy nhiên, các file hiӋn nay đưӧc chӍ ra bao gӗm cҧ tên thư mөc
do vұy 11 kí tӵ là không thӇ đáp ӭng đưӧc và hãng IBM và Microsoft đã đưa ra
khái niӋm thҿ file. Và tӯ phiên bҧn 2.0 cӫa DOS trӣ đi ngưӡi ta dùng thҿ file chӭ
không dùng FCB nӳa.

5.1.2 Thҿ file
      Thҿ file là mӝt tӯ 16 bit làm đҥi diӋn cho mӝt file. Khi ta muӕn sӱ dөng mӝt
file, ta trao cho DOS mӝt tên file có thӇ bao gӗm cҧ đưӡng dүn, còn DOS trҧ lҥi
mӝt thҿ file trong mӝt thanh ghi, khi đó ta muӕn thao tác gì vӟi file, ví dө như
đәi tên, mӣ file, đӑc file,... thì ta chӍ cҫn gӑi dӏch vө tương ӭng cӫa DOS sau khi
đã cung cҩp cho nó mӝt tham sӕ và xuҩt trình thҿ file trong thanh ghi nào đó
(BX). Chӭ không cҫn chӍ ra tên file nӳa.
     Mӝt điӅu cҫn biӃt đó là DOS coi các thiӃt bӏ ngoҥi vi như các file và nó gán
cho mӛi file này mӝt thҿ file. Do đó ta có thӇ dùng các dӏch vө file cӫa DOS đӇ
truy nhұp vào các thiӃt bӏ vұt lý khác nhau thông qua thҿ file cӫa chúng. Sau đây
là mӝt sӕ thҿ file đã đưӧc DOS quy đӏnh sҹn :
Thҿ file                                  Tên thiӃt bӏ
0                                         ThiӃt bӏ vào chuҭn, thưӡng là bàn phím
1                                         ThiӃt bӏ ra chuҭn, thưӡng là màn hình
2                                         ThiӃt bӏ báo lӛi chuҭn
3                                         ThiӃt bӏ phө chuҭn
4                                         Máy in chuҭn




                                                                                70
5.2. Các dӏch vө dùng thҿ file cӫa DOS và các mã lӛi
5.2.1. Các dӏch vө dùng thҿ file cӫa DOS

5.2.1.1. Tҥo ra mӝt tӋp
     Hàm 3CH tҥo ra mӝt tӋp, mӣ nó đӇ truy nhұp đӑc ghi và chuyӇn giao mӝt tӯ
truy nhұp tӋp. Trong quá trình này mӝt tӋp có cùng tên đang tӗn tҥi sӁ bӏ ghi đè.
NӃu như muӕn tránh hұu quҧ này thì trưӟc hӃt ta phҧi thӱ mӣ tӋp này. NӃu sau
đҩy xuҩt hiӋn thông báo lӛi là tӋp không đưӧc tìm thҩy và ta có thӇ yên tâm tҥo
ra mӝt tӋp mӟi.
     Đҫu vào :
    y Nҥp vào thanh ghi AH giá trӏ 3CH : mov ah,3ch
    y DX trӓ tӟi xâu chӭa tên tӋp hoһc đưӡng dүn tӟi tӋp :
      lea dx, tên_tӋp
      Lưu ý tên tӋp là mӝt xâu kӃt thúc bӣi sӕ 0.
    y Nҥp vào CX thuӝc tính tӋp
    Đҫu ra:
    Khi dӏch vө đưӧc thӵc hiӋn tӕt:
    y CF=0
    y AX chӭa tӯ truy nhұp tӋp hay thҿ tӋp
    Khi dӏch vө thӵc hiӋn có lӛi:
    y CF=1
    y AX chӭa mã lӛi. AX=3 ~ đưӡng dүn không tìm thҩy, AX=4 ~ quá nhiӅu
       tӋp đưӧc mӣ, AX=5 ~ tӯ chӕi truy nhұp.
    Ví dө tҥo mӝt tӋp có tên là text1:
    .model small                                   xor cx,cx; dat thuoc tinh cho
    .data                                          ;tep
       pkey db "text1",0                           int 21h
    .stack 100h                                    ;thoat khoi chuong trinh
    .code                                          kt:
    start:                                         mov ah, 1
       mov ax,@data                                int 21h
       mov ds,ax                                  mov ax, 4c00h
       tao_tep_moi:                               int 21h
       lea dx,pkey; dx tro toi ten tep          end start
       mov ah,3ch


                                                                               71
5.2.1.2. Mӣ mӝt tӋp
     Dӏch vө 3DH mӣ mӝt tӋp đã đưӧc tҥo ra tӯ trưӟc và chuyӇn giao tӯ truy
nhұp tӋp (thҿ tӋp). Tӯ này sӁ đưӧc dùng đӇ đӑc/ghi,« lên tӋp sau khi mӣ tӋp
thành công.
     Đҫu vào:
    y Nҥp vào AH giá trӏ 3DH
    y DX trӓ tӟi xâu chӭa tên tӋp hoһc đưӡng dүn tӟi tӋp :
      lea dx, biӃn_tên_tӋp
      Lưu ý tên tӋp là mӝt xâu kӃt thúc bӣi sӕ 0.
    Đҫu ra:
    Khi dӏch vө đưӧc thӵc hiӋn tӕt:
    y CF=0
    y AX chӭa tӯ truy nhұp tӋp hay thҿ tӋp
    Khi dӏch vө thӵc hiӋn có lӛi:
    y CF=1
    y AX chӭa mã lӛi. AX=3 ~ không tìm thҩy tӋp. AX=4 ~ quá nhiӅu tӋp
        đưӧc mӣ, AX=5 ~ tӯ chӕi truy nhұp, AX=12 ~ truy nhұp không thuұn
        tiӅn, chӍ rõ là AL đã không đưӧc đһt bҵng giá trӏ hӧp lý.
    Ví dө mӣ mӝt tӋp:
    .model small                                   mov al,0
    .data                                          mov ah,3dh
       pkey db "text1",0                           int 21h
       write db 128 dup(?)                       jc kt
       read db 128 dup(?)                        mov bx,ax
    .stack 100h                                  kt:
    .code                                        mov ah, 1
    start:                                       int 21h
       mov ax,@data                              mov ax, 4c00h
       mov ds,ax                                 int 21h
       mo_tep:                                end start
       lea dx,pkey

5.2.1.3. Khóa mӝt tӋp
     Dӏch vө 3EH khóa mӝt tӋp. Dӏch vө này thưӡng đưӧc sӱ dөng sau khi các
thao tác vӟi tӋp đã đưӧc hoàn tҩt.


                                                                        72
Đҫu vào:
    y Nҥp vào AH giá trӏ 3EH
    y Nҥp nào BX thҿ tӋp (thưӡng đã có sҹn sau khi tҥo mӟi hay mӣ tӋp)
    Xuҩt ra:
    y Khi dӏch vө không thành công AX=6~ tӯ truy nhұp tӋp không đúng
    Ví dө đóng mӝt tӋp lҥi sau khi mӣ:
    .model small                              int 21h
    .data                                     jc kt; nӃu mӣ tӋp có lӛi thì
       pkey db "text1",0                      nhҧy đӃn nhãn kӃt thúc
       write db 128 dup(?)                    mov bx,ax; đưa vào bx thҿ
       read db 128 dup(?)                       tӋp
    .stack 100h                                 ktt: ; đóng tӋp
    .code                                       mov ah,3eh
    start:                                      int 21h
       mov ax,@data                             kt: ; kӃt thúc chương trình
       mov ds,ax                                mov ah, 1
       mo_tep:                                  int 21h
       lea dx,pkey                              mov ax, 4c00h
       mov al,0                                 int 21h
       mov ah,3dh                             end start

5.2.1.4. Đӑc dӳ liӋu cӫa mӝt tӋp
    Dӏch vө 3FH chuyӇn các byte CX cӫa tӋp vào trong mӝt bӝ nhӟ đӋm đã
đưӧc cho trưӟc bӣi chương trình ӭng dөng.
    Đҫu vào:
    y Nҥp vào AH giá trӏ 3FH
    y Nҥp nào BX thҿ tӋp (thưӡng đã có sҹn sau khi tҥo mӟi hay mӣ tӋp)
    y Nҥp vào CX sӕ các byte phҧi đӑc
    y DS:DX chӭa đӏa chӍ cӫa vùng đӋm dӳ liӋu (thưӡng là mӝt trưӡng sӕ,
      trưӡng sӕ này sӁ chӭa các dӳ liӋu đӑc ra tӯ file)
    Xuҩt ra:
    Khi dӏch vө đưӧc thӵc hiӋn tӕt:
    y CF=0
    y AX chӭa sӕ byte phҧi đӑc, khi AX=0, sau đó hӃt tӋp (EOF)!
    Khi dӏch vө thӵc hiӋn có lӛi:
    y CF=1

                                                                              73
y AX chӭa mã lӛi. AX=5 ~ tӯ chӕi truy nhұp, AX=6 ~ thҿ file không hӧp
        lӋ.
    Ví dө đӑc nӝi dung cӫa tӋp có tên là text1:
    .model small                                jc kt; đӑc tӋp lӛi
    .data                                       cmp ax,0
       pkey db "text1",0                        je ktt ; hӃt tӋp
       write db 128 dup(?)                      mov cx,ax
       read db 128 dup(?)                         mov si,0
    .stack 100h                                   ht:; hiӇn thӏ thông tin
    .code                                         mov dl,read[si]
    start:                                        mov ah,2
       mov ax,@data                               int 21h
       mov ds,ax                                  inc si
       mo_tep:                                    loop ht
       lea dx,pkey                                jmp re
       mov al,0                                   ktt:; xӱ lý hӃt tӋp
       mov ah,3dh                                 mov ah,3eh
       int 21h                                    int 21h
       jc kt;mӣ tӋp có lӛi                        kt:
       mov bx,ax; bx chӭa thҿ file                mov ah, 1
       re: ; đӑc tӋp                              int 21h
       mov dx,offset read;                         mov ax, 4c00h
       mov cx,128; sӕ byte cҫn đӑc                int 21h
       mov ah,3fh; đӑc tӋp                      end start
       int 21h
    Trong ví dө trên ta, đӇ đӑc đưӧc tӋp, ta đӑc lҫn lưӧt 128 byte ra vùng đӋm
(mӝt trưӡng sӕ có đӝ dài 128 byte):
       mov dx,offset read; dx chͱa đ͓a ch͑ cͯa trưͥng s͙ (vùng đ͏m)
       mov cx,128 ; s͙ byte c̯n đ͕c b̹ng đ͡ dài cͯa trưͥng s͙
       mov ah,3fh; đ͕c ra vùng đ͏m
       int 21h
       jc kt ; nh̫y đ͇n k͇t thúc n͇u có l͟i trong khi đ͕c
       cmp ax,0 ; ki͋m tra xem đã k͇t thúc t͏p chưa
       je ktt ; n͇u là k͇t thúc t͏p thì nh̫y đ͇n nhãn x͵ lý k͇t thúc t͏p
       mov cx,ax; đưa s͙ kí t͹ (s͙ byte) vͳa đ͕c đưͫc vào thanh ghi l̿p
       mov si,0


                                                                            74
ht:
       mov dl,read[si]; đưa vào dl giá tr͓ n̹m trong tͳng byte cͯa trưͥng s͙ đ͋
                      ; hi͋n th͓ ra màn hình
       mov ah,2
       int 21h
       inc si
       loop ht          ; l̿p l̩i cho đ͇n khi cx=0 (hi͋n th͓ h͇t các byte cͯa đ͕c
                        ;đưͫc tͳ file ± đang n̹m trong trưͥng s͙)
     Quá trình đӑc vào vùng đӋm 128 byte dӳ liӋu cӫa file phҧi đưӧc thӵc hiӋn
lһp lҥi vì mӝt file có thӇ có nhiӅu hơn 128 byte dӳ liӋu. Ta dùng lӋnh nhҧy vô
điӅu kiӋn đӇ lһp.
      re: ; đ͕c 128 byte dͷ li͏u cͯa file vào vùng đ͏m
       mov dx,offset read
       mov cx,128
       mov ah,3fh
       int 21h
       jc kt
      cmp ax,0
       je ktt
       mov cx,ax
       mov si,0
       ht:
       mov dl,read[si]
       mov ah,2
       int 21h
       inc si
       loop ht
    jmp re      ; nh̫y l̩i nhãn cͯa đo̩n mã đ͕c 128 byte dͷ li͏u cͯa file vào
vùng đ͏m
    khi đã đӑc hӃt tӋp, ta tiӃn hành đóng tӋp lҥi đӇ bҧo vӋ dӳ liӋu cӫa tӋp :
       ktt:
       mov ah,3eh
       int 21h




                                                                              75
5.2.1.5. Ghi vào mӝt tӋp
     Dӏch vө 40H chuyӇn giao các byte CX tӯ mӝt bӝ nhӟ đӋm đã cho trưӟc
trong chương trình ӭng dөng vào mӝt tӋp:
     Đҫu vào:
    y Nҥp vào AH giá trӏ 40H
    y Nҥp nào BX thҿ tӋp (thưӡng đã có sҹn sau khi tҥo mӟi hay mӣ tӋp)
    y Nҥp vào CX sӕ các byte cҫn ghi
    y DX chӭa đӏa chӍ vùng đӋm
    Xuҩt ra:
    Khi dӏch vө đưӧc thӵc hiӋn tӕt:
    y CF=0
    y AX chӭa sӕ lưӧng byte đưӧc ghi
    Khi dӏch vө thӵc hiӋn có lӛi:
    y CF=1
    y AX chӭa mã lӛi. AX=5 ~ tӯ chӕi truy nhұp, AX=6 ~ thҿ tӋp không hӧp
       lӋ
    Ví dө vӅ ghi nӝi dung vào mӝt tӋp:
    .model small                               tiep:
    .data                                      mov cx,128
       pkey db "text1",0                       mov si,0
       write db 128 dup(?)                     nhap:
       read db 128 dup(?)                       mov ah,1
    .stack 100h                                 int 21h
    .code                                       xor ah,ah
    start:                                      cmp al,'?'
       mov ax,@data                             je kt_nap
       mov ds,ax                                mov write[si],al
       ;mӣ tӋp                                  inc si
       lea dx,pkey                              loop nhap
       mov al,0                                 mov cx,128
       mov ah,3dh                               mov dx,offset write
       int 21h                                  mov ah,40h
       jc kt                                    int 21h
       mov bx,ax                               jmp tiep
       ;ghi vào tӋp                             kt_nap:


                                                                         76
mov cx,si                                   kt:
       mov dx,offset write                        mov ah, 1
       mov ah,40h                                 int 21h
       int 21h                                    mov ax, 4c00h
       mov ah,3eh                                 int 21h
        int 21h                                end start
     ĐӇ ghi đưӧc nӝi dung vào tӋp, đҫu tiên bҥn phҧi mӣ tӋp ra, rӗi đưa thҿ tӋp
vào thanh ghi BX đӇ chuҭn bӏ ghi vào tӋp.
     ĐӇ ghi đưӧc vào tӋp, ta cҫn quy ưӟc sӁ ghi nào tӋp bao nhiêu byte, sau đó
dùng mӝt vòng lһp có sӕ lҫn lһp trùng vӟi sӕ byte muӕn ghi đӇ cho ngưӡi dùng
nhұp nӝi dung cҫn ghi nào:
     mov cx,128 ; s͙ ký t͹ (s͙ byte) mu͙n nh̵p vào
    mov si,0
    nhap:         ;cho ngưͥi dùng nh̵p dͷ li͏u vào
       mov ah,1
       int 21h
       xor ah,ah
       cmp al,'?' ; so sánh ký t͹ nh̵p vào vͣi ký t͹ k͇t thúc vi͏c nh̵p
       je kt_nap ; n͇u ngưͥi dùng không mu͙n nh̵p nͷa thì nh̫y đ͇n nhãn
                 ;kt_nap
       mov write[si],al ; chuy͋n ký t͹ ngưͥi dùng vͳa nh̵p vào vùng đ͏m
       inc si
    loop nhap     ; l̿p l̩i vi͏c nh̵p
    Sau khi ngưӡi dùng đã nhұp hӃt sӕ ký tӵ cҫn nhұp, ta ghi sӕ ký tӵ đó vào
vùng đӋm có tên là write bҵng dӏch vө 40h cӫa ngҳt 21h.
       mov cx,128
       mov dx,offset write
         mov ah,40h
         int 21h
     Đoҥn mã trên chӍ cho phép nhұp 128 byte vào file, đӇ nhұp đưӧc nhiӅu hơn
ta cҫn lһp lҥi đoҥn mã trên bҵng mӝt lӋnh nhҧy vô điӅu kiӋn ӣ cuӕi đoҥn mã:
     tiep: ; khͧi t̩o cho m͟i l̯n ghi 128 byte vào file
        mov cx,128
        mov si,0
        nhap:
         mov ah,1


                                                                            77
int 21h
        xor ah,ah
        cmp al,'?'
        je kt_nap
        mov write[si],al
       inc si
       loop nhap
       mov cx,128
       mov dx,offset write
       mov ah,40h
       int 21h
     jmp tiep ; l̿p l̩i đo̩n mã nh̵p 128 byte vào file
     Khi ngưӡi dùng nhҩn nút ³?´ thì vòng lһp trên sӁ kӃt thúc, ta cҫn ghi nhӳng
ký tӵ cuӕi cùng đưӧc nhұp vào file:
     kt_nap:
        mov cx,si
        mov dx,offset write
        mov ah,40h
        int 21h
        mov ah,3eh
        int 21h

5.2.1.6. Xóa mӝt tӋp
    Dӏch vө 41H cho phép xóa mӝt tӋp.
    Đҫu vào:
    y Nҥp vào AH giá trӏ 41H
    y DX trӓ tӟi xâu chӭa tên tӋp hoһc đưӡng dүn tӟi tӋp :
      lea dx, biӃn_tên_tӋp
      Lưu ý tên tӋp là mӝt xâu kӃt thúc bӣi sӕ 0.
    Xuҩt ra:
    Khi dӏch vө đưӧc thӵc hiӋn tӕt:
    y CF=0
    Khi dӏch vө thӵc hiӋn có lӛi:
    y CF=1
    y AH chӭa mã lӛi
    Ví dө:


                                                                             78
.model small
     .data
        pkey db "filetext",0
     .stack 100h
     .code
     start:
        mov ax,@data
        mov ds,ax

       lea dx,pkey
       mov ah,41h
       int 21h

       mov ax, 4c00h
       int 21h
     end start

5.2.1.7. Di chuyӇn con trӓ đӇ truy cұp trӵc tiӃp vào vӏ trí mӟi
    Dӏch vө 42H cho phép di chuyӇn con trӓ file đi mӝt sӕ byte kӇ tӯ mӝt vӏ trí
mӕc nào đó.
    Đҫu vào:
     y Nҥp vào AH giá trӏ 42H
     y Nҥp vào BX thҿ file
     y AL chӭa phương thӭc truy nhұp:
        0: so vӟi đҫu tӋp
        1: so vӟi vӏ trí hiӋn hành
        2: so vӟi cuӕi tӋp
     y CX:DX chӭa sӕ lưӧng byte cҫn chuyӇn
     Xuҩt ra:
     y DX:AX chӭa vӏ trí mӟi cӫa con trӓ
     Ví dө: di chuyӇn con trӓ đӃn byte nhӟ thӭ 3 tính tӯ đҫu file:
     .model small
     .data
        pkey db "text1",0
        dat db 128 dup(?)
     .stack 100h


                                                                            79
.code
    start:
       mov ax,@data
       mov ds,ax
        ;mӣ file ra đӇ đӑc
       lea dx,pkey
       mov al,0
       mov ah,3dh
       int 21h
       ;sau khi mӣ file, ta có thҿ file, đưa thҿ file vào BX
       mov bx,ax
       ;di chuyӇn con trӓ đi 3 byte kӇ tӯ đҫu file
       mov al,0; điӇm mӕc là đҫu file
       mov ah,42h
       xor cx,cx
       mov dx,3; di chuyӇn con trӓ đi 3 byte
       int 21h
       ;lúc này con trӓ đang đӭng ӣ byte thӭ 4, ta thӱ đӑc 1 byte cӫa file
       ;đӇ kiӇm tra xem con trӓ đã dӏch chuyӇn chưa?
       lea dx,dat
       mov cx,1
       mov ah,3fh
       int 21h
       ;hiӇn thӏ byte đưӧc đӑc
       mov dl,dat[0]
       mov ah,2
       int 21h
        ;kӃt thúc
       mov ax, 4c00h
       int 21h
     end start
     ĐӇ kiӇm tra bҥn hãy nhұp vào file text1 nӝi dung là ³123456789´, sau khi
đưӧc di chuyӇn 3 byte, con trӓ sӁ trӓ vào file thӭ 4 là sӕ ³4´. Khi chương trình
trên đưӧc thӵc thi bҥn sӁ nhìn thҩy sӕ 4 trên màn hình.




                                                                             80
5.2.1.8. Đәi tên tӋp
     Dӏch vө 56H cho phép xóa mӝt tӋp.
     Đҫu vào:
     y Nҥp vào AH giá trӏ 56H
     y DS:DX trӓ tӟi xâu chӭa tên cũ
     y ES:DI trӓ tӟi tên mӟi
     Xuҩt ra:
     Khi dӏch vө đưӧc thӵc hiӋn tӕt:
     y CF=0
     Khi dӏch vө thӵc hiӋn có lӛi:
     y CF=1
     y AH chӭa mã lӛi
     Ví dө: đәi tên tӋp tӯ text1   text
     .model small
     .data
        pkey db "text$",0
        pkey1 db "text",0
        dat db 128 dup(?)
        err db "co loi$"
     .stack 100h
     .code
     include lib2.asm
     start:
        mov ax,@data
        mov ds,ax
        ;chuyӇn xâu text sang ES:DI
        lea si,pkey1
        l1:
        lodsb
        xor ah,ah
        cmp ax,0
        je l2
        stosb
        jmp l1
       l2:


                                          81
;DI trӓ vào đҫu xâu pkey1, DX trӓ vào đҫu xâu pkey
         movsb
         lea dx,pkey
         mov di,0
         ;đәi tên
         mov ah,56h
         int 21h
         jnc kt
         hiens err
         kt:
         mov ax, 4c00h
         int 21h
     end start

5.2.2 Các mã lӛi trҧ vӅ
     Trong phiên bҧn DOS 4.0 có 91 lӛi khác nhau, các phiên bҧn vӅ sau thì sӕ
mã lӛi còn lӟn hơn. Sau đây là mӝt sӕ mà lӛi thưӡng gһp:
Mã lӛi             Ý nghĩa
1                  Sӕ hiӋu dӏch vө sai
2                  Không tìm thҩy file
3                  Không tìm thҩy đưӡng dүn
4                  Mӣ quá nhiӅu file mӝt lúc
5                  DOS tӯ chӛi không thӵc hiӋn thao tác này
6                  Dùng thҿ file bӏ hӓng
7                  Khӕi điӅu khiӇn MCB bӏ hӫy
8                  Không có đӫ bӝ nhӟ
15                 ChӍ đӏnh sai tên ә đĩa
16                 Không thӇ xóa thư mөc hiӋn thӡi
19                 Không thӇ ghi lên đĩa
21                 ә đũa chưa sҹn sàng
23                 Lӛi dӳ liӋu trên đĩa
25                 Lӛi tìm rãnh trên đĩa
27                 Không tìm thҩy sector
28                 Máy in không có giҩy
29                 Lӛi khi



                                                                          82
30   Lӛi đӑc
61   Hàng đӧi bӏ đҫy




                       83
Chương 6 Liên kӃt giӳa ngôn ngӳ assembly vӟi các ngôn ngӳ
                           bұc cao
6.1 Mӣ đҫu
     NhiӅu khi trong lұp trình, chúng ta muӕn viӃt mӝt chương trình mà trong đó
có mӝt phҫn đưӧc viӃt bҵng ngôn ngӳ bұc thҩp như hӧp ngӳ và mӝt phҫn đưӧc
viӃt bҵng ngôn ngӳ bұc cao đӇ có thӇ tұn dөng đưӧc sӭc mҥnh cӫa cҧ hai loҥi
ngôn ngӳ này.
     Nhìn chung, viӋc liên kӃt hӧp ngӳ vӟi bҩt kǤ ngôn ngӳ bұc cao nào vӅ cơ
bҧn là giӕng nhau. Do vұy trong giáo trình này chúng ta sӁ chӍ tìm hiӇu vӅ cách
liên kӃt hӧp ngӳ vӟi C và Pascal.

6.2. Liên kӃt assembly vӟi ngôn ngӳ C
    Có hai cách đӇ liên kӃt giӳa C vӟi Assembler:
    y Cách 1: chèn các khӕi lӋnh hӧp ngӳ vào chương trình đưӧc viӃt bҵng
      ngôn ngӳ C ± inline assembly. Đây là phương pháp khá đơn giҧn và
      nhanh vì vӟi tӯ khóa asm đӭng trưӟc mӛi lӋnh, chúng ta có thӇ dӉ dàng
      đưa các lӋnh cӫa hӧp ngӳ vào giӳa các dòng lӋnh cӫa C.
    y Cách 2: viӃt tách biӃt nhiӅu module:
         o Bҵng ngôn ngӳ C
           o Bҵng hӧp ngӳ
        Sau đó tiӃn hành dӏch và liên kӃt chúng lҥi vӟi nhau. So vӟi cách 1, cách
        này sӁ phӭc ҥp hơn cho ngưӡi lұp trình song sӁ tránh đưӧc nhӳng nhưӧc
        điӇm mà cách 1 gһp phҧi.

6.2.1. Inline assembly trong C
  Cơ ch͇: Chèn khӕi lӋnh ASM vào chương trình đưӧc viӃt bҵng C/C++
  Cú pháp:
    Các câu lӋnh C
    ASM lӋnh ASM
    ASM lӋnh ASM
    ASM lӋnh ASM
    Các câu lӋnh C
    hoһc cách khác:
    Các câu lӋnh C
    ASM { // dҩu ngoһc phҧi cùng mӝt dòng


                                                                              84
khӕi lӋnh ASM
    }
    Các câu lӋnh C
    Ví dͭ Tính Tәng 2 sӕ nguyên:
    #include "conio.h"
    #include "stdio.h"
    int a,b;
    void main(){
     clrscr();
     printf("moi nhap an");
     scanf("%d",&a);
     printf("moi nhap bn");
     scanf("%d",&b);
     asm mov ax,b
     asm add a,ax
     printf("tong la :%d",a);
     getch();
    }
    Quá trình dӏch cӫa chương trình viӃt bҵng ngôn ngӳ C có xen các dòng lӋnh
ASM sӁ tiӃn hành theo mӝt trình tӵ như sau:
    y Chương trình Turbo C sӁ dӏch tӋp nguӗn có đuôi .c sang tӋp .asm.
    y Chương trình dӏch TASM sӁ tiӃp tөc dӏch tӋp .asm sang tӋp có đuôi .obj.
    y TLINK sӁ thӵc hiӋn viӋc liên kӃt đӇ tҥo tӋp có đuôi .exe.
    Nhưͫc đi͋m cͯa vi͏c inline assembly C:
    y Các lӋnh nhҧy cӫa inline assembly chӍ có thӇ nhҧy đӃn các nhãn C
      (không thӇ nhҧy tӯ các nhãn inline assembly ra phҫn ngôn ngӳ C chӭ thӇ
        không cho phép chiӅu ngưӧc lҥi và cũng không thӇ thӵc hiӋn các lӋnh
        nhҧy trong lòng phҫn inline).
    y Nhãn nҵm trong phҫn cӫa C không thӇ là toán hҥng trong tҩt cҧ các lӋnh
      assembler cӫa inline assembly (trӯ các lӋnh nhҧy).

6.2.2. ViӃt tách biӋt nhiӅu module trong C
    Cách thưӡng dùng trong viӋc liên kӃt giӳa các chương trình viӃt bҵng ngôn
ngӳ C vӟi các chương trình viӃt bҵng ngôn ngӳ assembly là viӃt hoàn toàn tách
biӋt nhiӅu module riêng lҿ trong ngôn ngӳ C và ngôn ngӳ assembly. TiӃn hành



                                                                           85
dӏch các module theo tӯng module mӝt sau đó liên kӃt lҥi vӟi nhau đӇ tҥo ra các
file thi hành đưӧc.
      Trưӟc khi tiӃn hành viӃt tách biӋt, chúng ta cҫn phҧi chú ý đӃn 3 vҩn đӅ sau:
      Vҩn đӅ 1: khi viӃt tách biӋt module C và module ASM thì vҩn đӅ cҫn giҧi
quyӃt đҫu tiên là vҩn đӅ đa tӋp. ĐӇ 2 module có thӇ sӱ dөng các biӃn và các hàm
cӫa nhau, ta cҫn phҧi khai báo public các hàm và biӃn cho phép đưӧc sӱ dөng
chung, khi sӱ dөng các hàm và các biӃn này thì ta phҧi khai báo extern:
     y Không cҫn khai báo public vӟi các hàm, biӃn cӫa C, mһc đӏnh nó đã
       đưӧc coi là public
     y Cҫn khai báo public cho các hàm, biӃn dùng chung trong ASM
     y Khi sӱ dөng lҥi các hàm, biӃn cӫa C, ASM cҫn khai báo extrn: extrn
       tên_biӃn: kiӇu
     y Khi sӱ dөng lҥi các hàm, biӃn trong ASM, C cҫn khai báo extern: extern
        kiӇu tên_hàm(đӕi)
     Vҩn đӅ 2: trong module ASM, phҧi thêm dҩu µ_¶ trưӟc mӑi nhãn dùng
chung vӟi C
     Lưu ý: đӕi vӟi C++, ta khai báo extern hàm trưӟc, rӗi sau đó dùng lӋnh sau
đӇ dӏch tӯ file .cpp .asm: tcc ±S file.cpp
     Sau đó mӣ file .asm vӯa đưӧc dӏch ra, ta sӁ thҩy tên chương trình con ӣ
cuӕi file, thông thưӡng, C sӁ thêm ký tӵ @ và $ vào tên hàm. Ví dө, hàm có tên
là func1, thì C sau khi dӏch ra ASM sӁ đәi tên nó thành @func1$qv.
     Vҩn đӅ 3: Tên hàm cӫa ASM có giá trӏ trҧ vӅ nҵm trong AX hoһc DX:AX,
vì vұy cҫn chú ý đưa kӃt quҧ vào AX khi viӃt hàm trong ASM.
     Sau khi chúng ta đã giҧi quyӃt đưӧc 3 vҫn đӅ trên và có hai tӋp viӃt bҵng C
và bҵng assembly cӫa mӝt chương trình thì chúng ta tiӃn hành dӏch và liên kӃt
bҵng lӋnh sau:
      Tcc ±ms/ls ±Ic:/tc/include ±Lc:/tc/lib tep1.cpp tep2.asm
      LӋnh dӏch trên báo cho chương trình dӏch Turbo C biӃt trưӟc tên phҧi dӏch
file tep1.cpp thành file tep1.obj sau đó gӑi chương trình dӏch TASM dӏch file
tep2.asm thành file tep2.obj và cuӕi cùng là gӑi TLINK đӇ liên kӃt tep1.obj và
tep2.obj thành file thi hành đưӧc tep1.exe.
      ViӋc viӃt tách biӋt các module rҩt có lӧi cho các chương trình có sӕ lưӧng
lӋnh assembly lӟn vì trong trưӡng hӧp này có thӇ sӱ dөng toàn bӝ khҧ năng cӫa
chương trình dӏch assembly và dӏch phҫn assembly trong inline assembly. Không
nhӳng thӃ phương pháp này cho ta khҳc phөc các nhưӧc điӇm cӫa inline
assembly vҩp phҧi.

                                                                                86
Ví dө: viӃt mӝt chương trình đơn giҧn, cho nhұp vào mӝt biӃn, sau đó tăng
giá trӏ cӫa biӃn đó lên 1 đơn vӏ và hiӋn giá trӏ vӯa đưӧc tăng đó lên màn hình. Ta
sӁ trao nhiӋm vө nhұp và hiӇn thӏ biӃn cho C, và trao nhiӋm vө tăng giá trӏ cho
ASM:
      Module C:
       #include "conio.h"
       #include "stdio.h"
       int a;
       extern int tang();
       void main(){
       clrscr;
       printf("nhap a");scanf("%d",&a);
       printf("%d",tang());
       getch();
       }
       Module ASM:
       .model small
       .data
        extrn _a:word
       .code
       begin:
        public @tang$qv
        @tang$qv proc
          mov ax,_a
          inc ax
          ret
        @tang$qv endp
       end begin

6.3 Liên kӃt assembly vӟi ngôn ngӳ pascal
6.3.1. Inline assembly trong Pascal
     Cũng giӕng như C,đӇ inline assembly trong Pascal chúng ta đһt các khӕi
lӋnh assembler vào chương trình đưӧc viӃt bҵng ngôn ngӳ Pascal tҥi nơi nào
chúng ta cҧm thҩy cҫn thiӃt.
       Dҥng tәng quát cӫa inline assembly trong chương trình viӃt bҵng Pascal như
sau:

                                                                               87
asm
      các lӋnh asembler
    end;
    Mӛi khi chương trình dӏch Pascal gһp tӯ khóa asm trong dòng lӋnh inline
assembly thì chương trình dӏch sӁ chuyӇn dòng lӋnh Assembly này vào dӏch vӟi
viӋc quy chiӃu biӃn Pascal ra dҥng tương ӭng cӫa assembler đӇ thӵc hiӋn.
     Ví dө: viӃt chương trình tính tәng hai sӕ đưӧc nhұp vào tӯ bàn phím
     var a,b:integer;
     begin
     writeln('moi nhap a:');readln(a);
     writeln('moi nhap b:');readln(b);
     asm
     mov ax,b;
     add a,ax;
    end;
    writeln('tong la:',a);
    readln;
    end.
    Nhưӧc điӇm cӫa viӋc inline assembly trong Pascal:
    y Các lӋnh cӫa ASM đưӧc dӏch nhӡ qua chương trình dӏch cӫa Pascal
    y Các lӋnh nhҧy cӫa inline assembly chӍ có thӇ nhҧy đӃn các nhãn Pascal.

6.3.2. ViӃt tách biӋt nhiӅu module trong Pascal
     Tương tӵ như C, viӋc viӃt tách biӋt các nhiӅu module trong Pascal cũng có
nghĩa là chúng ta viӃt chương trình đa tӋp, vӟi các tӋp Pascal và ASM riêng biӋt.
     Chúng ta cҫn giҧi quyӃt các vҩn đӅ sau khi tiӃn hành viӃt tách biӋt:
     Vҩn đӅ 1: phҧi khai báo public cho các biӃn, hàm dùng chung. Khi sӱ dөng
phҧi khai báo extern:
    y Các biӃn, hàm trong Pascal không cҫn khai báo public
    y Các biӃn, hàm trong ASM phҧi khai báo public
    y Các biӃn, hàm muӕn đưӧc sӱ dөng lҥi, phҧi khai báo extrn trong ASM:
      extrn tên_biӃn: kiӇu
    y Các biӃn, hàm muӕn đưӧc sӱ dөng lҥi, phҧi khai báo external trong
      pascal: procedure (function)(đӕi sӕ):kiӇu;external;
    Vҩn đӅ 2: vҩn đӅ near/far cӫa chương trình con:



                                                                              88
Như chúng ta đã biӃt, chương trình con near là chương trình con nҵm cùng
segment vӟi chương trình chính, chương trình con far thì nҵm khác segment vӟi
chương trình chính. Pascal quy ưӟc:
    y Các chương trình con đưӧc khai báo ӣ phҫn interface cӫa Unit luôn là
      far
     y Các chương trình con đưӧc khai báo trong chương trình đưӧc coi là near
     Song vì mӝt lý do nào đó thì chương trình con cũng có thӇ yêu cҫu far, đӇ
làm đưӧc điӅu này, ta cҫn dùng lӋnh điӅu khiӇn {$F+} đӇ quy ưӟc vӟi Pascal
rҵng các chương trình con đưӧc dӏch vӟi khai bào {$F+} sӁ là far. ĐӇ quay vӅ
quy ưӟc ban đҫu, ta dùng lӋnh điӅu khiӇn {$F-}
     Vҩn đӅ 3: cҫn phҧi dùng lӋnh điӅu khiӇn {$L tên_file_asm.obj} đӇ báo cho
chương trình dӏch cӫa pascal tìm đӃn tӋp ASM có thӇ ghép nӕi vӟi nó. Do đó sau
khi viӃt chương trình asm song, ta tiӃn hành biên dӏch thành file obj, viӃt file
pascal và biên dӏch chương trình pascal là đưӧc, không cҫn phҧi liên kӃt file
bҵng tay như vӟi C.
     Ví du: tương tӵ ví dө trong phҫn viӃt tách biӋt vӟi ngôn ngӳ C, ta có các
module Pascal và ASM như sau:
   var a:integer;
   {$F+}
   function tang:integer;external;
   {$L vd2[.obj]}
   {$F-}
   begin
     writeln('moi nhap ');
     readln(a);
     writeln(tang);
     readln
    end.
    Module ASM:
    .model large
    .data
     extrn a:word
    .code
    begin:
     public tang
     tang proc

                                                                             89
mov ax,a
   inc ax
   ret
 tang endp
end begin




              90

Link asm in another language

  • 1.
    CHƯƠNG 1: MӢĐҪU ............................................................................................................................. 3 1.1. NHҳC LҥI CÁC HӋ ĐӃM ......................................................................................................................... 3 1.1.1. Các h͏ đ͇m ............................................................................................................................... 3 1.1.2. Chuy͋n đ͝i s͙ giͷa các h͏ đ͇m ................................................................................................. 3 1.2. VI Xӱ LÝ 8086, TұP LӋNH VÀ CÁC MODE ĐӏA CHӍ .................................................................................. 6 1.2.1. Vi x͵ lý 8086 ............................................................................................................................ 6 1.2.2. Các thanh ghi và mode đ͓a ch͑ trong 8086 ................................................................................ 7 1.2.3. Các mode đ͓a ch͑ cͯa 8086 ..................................................................................................... 10 1.3. NGҳT .............................................................................................................................................. 14 1.4. GIӟI THIӋU VӅ HӧP NGӳ ..................................................................................................................... 16 1.4.1. L̵p trình b̹ng hͫp ngͷ .......................................................................................................... 16 1.4.2. Các bưͣc vi͇t chương trình hͫp ngͷ ....................................................................................... 17 1.4.3. C̭u trúc m͡t chương trình hͫp ngͷ d̩ng segment đơn gi̫n .................................................... 19 1.4.4. C̭u trúc cͯa m͡t chương trình segment d̩ng chu̱n ............................................................... 24 CHƯƠNG 2. LұP TRÌNH VӟI DEBUG ................................................................................................. 30 2.1. TәNG QUAN VӅ DEBUG .................................................................................................................... 30 2.1.1. Đ̿c đi͋m cͯa Debug............................................................................................................... 30 2.1.2. Khͧi đ͡ng và thoát kh͗i Debug ............................................................................................... 30 2.2. CÁC LӋNH CӫA DEBUG ..................................................................................................................... 30 2.2.1. Nhóm các l͏nh biên so̩n chương trình.................................................................................... 30 2.2.2. Nhóm các l͏nh d͓ch chuy͋n dͷ li͏u ......................................................................................... 32 2.2.3. Nhóm l͏nh quan sát ................................................................................................................ 34 2.2.4. Nhóm l͏nh thi hành chương trình ............................................................................................ 34 CHƯƠNG 3: CÁC LӋNH CӫA ASSEMBLY ......................................................................................... 36 3.1 CÁC LӋNH VұN CHUYӇN Dӳ LIӋU ......................................................................................................... 36 3.2 CAC LӋNH Sӕ HӑC .............................................................................................................................. 39 3.3 CAC LӋNH THAO TAC MӭC BIT ........................................................................................................... 43 3.4 CAC LӋNH THAO TAC VӟI DÃY (CHUӛI) ............................................................................................... 46 3.5 CAC LӋNH NHҧY ± CHUYӇN DIӅU KHIӇN .............................................................................................. 48 3.6 CAC LӋNH THAO TAC VӟI Cӡ VA DIӅU KHIӇN Bӝ.................................................................................... 50 CHƯƠNG 4 CHƯƠNG TRINH CON VA CHƯƠNG TRINH DA TӋP ................................................ 52 4.1 THӫ TөC ± CHƯƠNG TRINH CON ......................................................................................................... 52 4.1.1 Cơ ch͇ làm vi͏c cͯa chương trình con...................................................................................... 52 4.1.2 C̭u trúc cͯa chương trình con ................................................................................................. 52 4.1.3 V̭n đ͉ chuy͋n giao tham s͙ ..................................................................................................... 53 4.1.4 V̭n đ͉ b̫o v͏ các thanh ghi .................................................................................................... 54 4.1.5. M͡t s͙ ví dͭ ............................................................................................................................ 54 4.2 CHƯƠNG TRÌNH ĐA TӋP ..................................................................................................................... 58 4.2.1 L͏nh đi͉u khi͋n PUBLIC ......................................................................................................... 58 4.2.2 L͏nh đi͉u khi͋n EXTERN......................................................................................................... 59 4.2.3 L͏nh đi͉u khi͋n GLOBAL ....................................................................................................... 59 4.2.4. T͏p INCLUDE và cách dùng................................................................................................... 62 4.2.5 MACRO và v̭n đ͉ liên quan .................................................................................................... 65 4.2.5.1. Chͱc năng ........................................................................................................................... 65 CHƯƠNG 5: CÁC THAO TÁC VӟI TӋP ............................................................................................... 70 5.1 THҿ FILE (F ILE HANDLES) ................................................................................................................ 70 5.1.1 Kh͙i đi͉u khi͋n file ± FCB (File Control Blocks)...................................................................... 70 5.1.2 Th̓ file .................................................................................................................................... 70 5.2. CAC DӏCH Vө DUNG THҿ FILE CӫA DOS VA CAC MÃ LӛI ...................................................................... 71 5.2.1. Các d͓ch vͭ dùng th̓ file cͯa DOS .......................................................................................... 71 5.2.2 Các mã l͟i tr̫ v͉ ..................................................................................................................... 82 CHƯƠNG 6 LIÊN KӃT GIӳA NGÔN NGӳ ASSEMBLY VӟI CÁC NGÔN NGӳ BұC CAO .............. 84 6.1 Mӣ ĐҫU ............................................................................................................................................ 84 6.2. LIÊN KӃT ASSEMBLY VӟI NGÔN NGӳ C............................................................................................... 84 1
  • 2.
    6.2.1. Inline assemblytrong C .......................................................................................................... 84 6.2.2. Vi͇t tách bi͏t nhi͉u module trong C ........................................................................................ 85 Khai báo cͯa ASM: Gi͙ng như đa t͏p thu̯n tuý .................................... Error! Bookmark not defined. VҩN ĐӅ 2 ...................................................................................... ERROR! BOOKMARK NOT DEFINED. 6.3 LIÊN KӃT ASSEMBLY VӟI NGÔN NGӳ PASCAL....................................................................................... 87 6.3.1. Inline assembly trong Pascal................................................................................................... 87 6.3.2. Inline assembly trong Pascal................................................................................................... 88 2
  • 3.
    Chương 1: MӢĐҪU 1.1. Nhҳc lҥi các hӋ đӃm 1.1.1. Các hӋ đӃm Trong cuӝc sӕng hàng ngày chúng ta thưӡng dùng hӋ cơ sӕ 10 ± hӋ đӃm đưӧc hình thành tӯ 10 kí sӕ tӯ 0 đӃn 9 - đӇ biӇu diӉn các giá trӏ sӕ. ĐiӅu này rҩt tӵ nhiên vì tӯ xa xưa con ngưӡi bình thưӡng đã biӃt dùng 10 ngón tay cӫa mình đӇ như là mӝt công cө tính toán sơ đҷng. Trong thӃ giӟi máy tính thì khác, do máy tính đưӧc cҩu tҥo nên tӯ các mҥch điӋn tӱ và các mҥch này chӍ có hai trҥng thái có điӋn và không có điӋn. Do đó đӇ biӉu diӉn mӝt giá trӏ sӕ trong máy tính ngưӡi ta sӱ dөng hӋ đӃm cơ sӕ hai hay hӋ đӃm nhӏ phân (Binary number system). Trong hӋ đӃm này chӍ tӗn tҥi hai chӳ sӕ 0 và 1 tương ӭng vӟi hai trҥng thái có điӋn và không có điӋn cӫa các mҥch điӋn tӱ. NӃu dùng hӋ cơ sӕ hai đӇ biӇu diӉn các sӕ có giá trӏ lӟn sӁ gһp bҩt tiӋn là sӕ hӋ hai thu đưӧc quá dài, thí dө: 255 = 1111 1111 ĐӇ viӃt kӃt quҧ biӉu diӉn các sӕ cho gӑn lҥi ngưӡi ta sӱ dөng các các hӋ đӃm khác như hӋ cơ sӕ 8(bát phân) và hӋ cơ sӕ 16 (thұp lөc, hexa). Bҧng sau đây trình bày mӝt sӕ hӋ đӃm cơ bҧn: HӋ đӃm Cơ sӕ Sӕ kí sӕ và kí tӵ Dҥng kí sӕ và kí tӵ Nhӏ phân (Binary) 2 2 0,1 Bát phân (Octal) 8 8 0,1,2,3,4,5,6,7 Thұp phân (Decimal) 10 10 0,1,2,3,4,5,6,7,8,9 Thұp lөc phân 16 16 0,1,2,3,4,5,6,7,8,9, (Hexadecimal) A,B,C,D,E,F Bҧng 1.1. Các hӋ đӃm cơ bҧn Ngoài ra, hӋ đӃm BCD còn đưӧc sӱ dөng đӇ biӇu diӉn các sӕ tӯ 0 đӃn 9 vӟi 4 bit (4 bit=1 nibble) nhӏ phân. 1.1.2. ChuyӇn đәi sӕ giӳa các hӋ đӃm 1.1.2.1. ChuyӇn đәi giӳa hӋ thұp phân và hӋ nhӏ phân a. ChuyӇn tӯ hӋ thұp phân sang hӋ nhӏ phân Quy tҳc: Lҩy phҫn nguyên chia cho 2 và ghi lҥi phҫn dư, tiӃp tөc lҩy thương chia cho 2 và ghi lҥi phҫn dư. Lһp lҥi quá trình cho đӃn khi thương bҵng 0. Sau đó viӃt các sӕ dư theo chiӅu tӯ phép chia cuӕi cùng đӃn phép chia đҫu tiên. 3
  • 4.
    Thí dө: (33)10 = (100001)2 33 2 1 16 2 0 8 2 0 4 2 0 2 2 0 1 2 1 0 Hình 1.1. Cách đәi mӝt sӕ hӋ mưӡi sang hӋ hai Quy tҳc đәi sӕ thұp phân hӋ mưӡi sang hӋ hai: Lҩy sӕ cҫn đәi nhân vӟi 2, tích gӗm phҫn nguyên và phҫn lҿ. Lҩy phҫn lҿ nhân tiӃp vӟi 2 cho đӃn khi nào tích thu đưӧc bҵng 1 thì dӯng lҥi. Chӑn riêng phҫn nguyên cӫa các tích thu đưӧc và viӃt theo thӭ tӵ tӯ phép nhân đҫu tiên đӃn phép nhân cuӕi cùng. Thí dө: (0,125)10 = (0,001)2 0,125 x 2 = 0 ,250 0,250 x 2 = 0 ,50 0,50 x 2 = 1 ,0 Hình 1.2. Các đәi mӝt sӕ thұp phân hӋ mưӡi sang hӋ hai b. ChuyӇn tӯ hӋ nhӏ phân sang hӋ thұp phân: ĐӇ chuyӇn tӯ hӋ nhӏ phân sang thұp phân ta tính tәng các tích sӕ giӳa các hӋ sӕ vӟi các trӑng sӕ 2i tҥi tӯng vӏ trí thӭ i. Thí dө: (1110,11)2 = 1.23 + 1.22 + 1.21 + 0.20 + 1.2-1 + 1.2-2 = 8 + 4 + 2 + 0,5 + 0,25 = (14,75)10 1.1.2.2. ChuyӇn đәi giӳa thұp lөc hoһc hӋ bát phân sang hӋ nhӏ phân 4
  • 5.
    Quy tҳc: Nhóm4 bit (hoһc 3 bit cho hӋ bát phân) bҳt đҫu tӯ bit ngoài cùng bên phҧi, tính giá trӏ sӕ hӑc theo quy luұt giá trӏ riêng cho tӯng nhóm. ViӃt các giá trӏ này liên tiӃp nhau. Thí dө: Cho sӕ nhӏ phân: 11110101 chuyӇn sang hӋ thұp lөc và hӋ bát phân như sau: (11 110 101) 3 6 5 trong hӋ bát phân là sӕ 365 (1111 0101) 15 5 F5 trong hӋ thұp lөc là sӕ F5 Khi cҫn chuyӇn ngưӧc lҥi làm tương tӵ. Thí dө: (120)8 = (001 010 000) 2 (120)16 = (0001 0010 0000)2 1.3. Các phép toán bit 1.3.1. Phép toán AND Kí hiӋu: & Ý nghĩa: Nhân logic trên các bit. Phép toán này thӵc hiӋn trên tӯng cһp bit tương ӭng cӫa các toán hҥng theo quy tҳc trong bҧng sau: A B A&B 0 0 0 0 1 0 1 0 0 1 1 1 Bҧng 1.3. Bҧng chân lý phép toán AND trên bit 1.1.3. Các phép toán logic 1.1.3.1. Phép toán OR Kí hiӋu: | Ý nghĩa: Cӝng logic trên các bit. Phép toán này thӵc hiӋn trên tӯng cһp bit tương ӭng cӫa các toán hҥng theo quy tҳc trong bҧng sau: A B A|B 0 0 0 0 1 1 1 0 1 1 1 1 Bҧng 1.4. Bҧng chân lý phép toán OR trên bit 1.1.3.2. Phép toán XOR Kí hiӋu: ^ 5
  • 6.
    Ý nghĩa: Phépcӝng logic trên các bit. Thӵc hiӋn trên tӯng cһp bit tương ӭng cӫa các toán hҥng theo quy tҳc trong bҧng sau. A B A^B 0 0 0 0 1 1 1 0 1 1 1 0 Bҧng 1.5. Bҧng chân lý phép toán XOR trên bit 1.1.3.3. Phép toán NOT Kí hiêu: ~ Ý nghĩa: phép đҧo bit, đәi các giá trӏ trong mӛi bit cӫa toán hҥng x tӯ 0->1, 1->0. 1.1.3.4. Phép toán dӏch trái/phҧi - x SHR i: Phép dӏch phҧi, cho giá trӏ có đưӧc tӯ sӕ nguyên x sau khi dӏch sang phҧi i bit; các sӕ 0 sӁ lҩp đҫy các kӃt quҧ bên trái nӃu là sӕ nguyên dương; nӃu không phҧi là sӕ nguyên dương thì sӕ 1 sӁ lҩp đҫy các kӃt quҧ bên trái. Thí dө: 5 >> 2 = 1 ( 0101 >> 2 = 0001) - x SHL i: Phép dӏch trái, cho giá trӏ có đưӧc tӯ sӕ nguyên x sau khi dӏch sang trái i bit; các sӕ 0 sӁ lҩp đҫy các kӃt quҧ ӣ bên phҧi. 5 << 2 = 20 1.2. Vi xӱ lý 8086, tұp lӋnh và các mode đӏa chӍ 1.2.1. Vi xӱ lý 8086 Vi xӱ lý (VXL) làm nhiӋm vө cӫa bӝ xӱ lý trung tâm CPU nên thưӡng đươc gӑi là CPU và đưӧc đһt ӣ trung tâm bҧn mҥch chính. VXL đưӧc chӃ tҥo trên cơ sӣ công nghӋ chӃ tҥo các mҥch vi điӋn tӱ tích hӧp rҩt lӟn vӟi các phҫn tӱ cơ bҧn là các Transistor. Các máy tính IBM tương thích vӟi VXL cӫa hãng Intel nên ta sӁ đi tìm hiӇu vӅ VXL cӫa intel. Hӑ VXL cӫa Intel 80x86 vӟi x là 1,2,3,4, đӃn sӕ 5 thì đәi thành Pentium. Ngoài ra còn có các VXL cӫa các hãng khác. 80x86 là VXL 16 bit, tӭc là nó có bus dӳ liӋu 16 bit. Do vұy nó có khҧ năng truy xuҩt dӳ liӋu 2 byte mӝt lҫn. bus đӏa chӍ có đӝ rӝng 20 bit. Tӭc là nó có khҧ năng xác đӏnh đӏa chӍ cӫa 220 ô nhӟ = 1MB đӏa chӍ byte nhӟ vұt lý. 6
  • 7.
    VӅ mһt cҩutrúc, CPU hay VXL có hai phҫn chӭc năng đӝc lұp đó là BIU và EU: BIU là đơn vӏ ghép nӕi, nó thӵc hiӋn tҩt cҧ các công viӋc vӅ BUS cho EU. Nó thiӃt lұp khâu nӕi vӟi thӃ giӟi bên ngoài là các Bus đӏa chӍ, sӕ liӋu và điӅu khiӇn. BIU bao gӗm các thanh ghi đoҥn nhӟ, thanh ghi con trӓ lӋnh và bӝ điӅu khiӇn logic Bus. EU là đơn vӏ thi hành lӋnh, EU gӗm hai khӕi: khӕi tính toán sӕ hӑc và logic ALU và khӕi điӅu khiӇn CU. EU có trách nhiӋm xӱ lý dӳ liӋu, nó duy trì trҥng thái cӫa VXL, kiӇm soát các thanh ghi đa năng và toán hҥng lӋnh. EU gӗm các thanh ghi đa năng, thanh ghi cӡ. Khi VXL hoҥt đӝng, dӳ liӋu đưӧc truyӅn giӳa VXL và thiӃt bӏ vào ra khi có yêu cҫu cӫa EU. Chúng không đưӧc truyӅn trӵc tiӃp tӟi EU mà phҧi qua mӝt vùng nhӟ RAM có dung lưӧng nhӓ hơn 6 byte gӑi là hàng nhұp lӋnh trưӟc PQ. Rӗi sau đó mӟi đưӧc truyӅn vào đơn vӏ lӋnh IU. TiӃp đó IU sӁ điӅu khiӇn EU đӇ cho lӋnh đưӧc thӵc hiӋn bӣi ALU. Mӝt chu kì lӋnh cӫa 8086 có thӇ coi đơn giҧn gӗm hai thӡi khoҧng: lҩy lӋnh tӯ bӝ nhӟ và thӵc hiӋn lӋnh. Khi EU đang thӵc hiӋn lӋnh trưӟc thì BIU đã tìm và lҩy lӋnh tiӃp theo tӯ bӝ nhӟ, giҧi mã nó và nҥp vào PQ vào, khiӃn cho thӡi gian lҩy lӋnh cӫa 8086 có thӇ coi là bҵng 0. Sau này chúng ta biӃt đӃn cơ chӃ này trong các VXL vӅ sau cӫa Intel đó là cơ chӃ đưӡng ӕng. 1.2.2. Các thanh ghi và mode đӏa chӍ trong 8086 Thanh ghi là mӝt bӝ nhӟ dҥng RAM đưӧc tích hӧp ngay trong VXL. Vì tӕc đӝ truy cұp các thanh ghi nhanh hơn RAM, nên thanh ghi đưӧc dùng đӇ lưu trӳ các dӳ liӋu tҥm thӡi cho quá trình xӱ lý và tính toán bên trong máy tính. 1.2.2.1. Cách đӏnh đӏa chӍ byte nhӟ trong 8086 Bus đӏa chӍ cӫa 8086 có 20 bit, đӏnh đӏa chӍ cho 1 MB bӝ nhӟ, trong khi đó các thanh ghi trong 8086 đӅu có đӝ rӝng là 16 bit, nên phҧi có cơ chӃ đӇ đánh đӏa chӍ logic và vұt lý cho không gian nhӟ 1MB. Cách đánh đӏa chӍ như sau: Chương trình sӁ chia không gian nhӟ vұt lý thành các đoҥn nhӟ logic, vӟi kích thưӟc 64Kbyte mӛi đoҥn, các byte trong đoҥn là liên tiӃp nhau. Mӛi đoҥn nhӟ đưӧc chương trình gҳn cho mӝt đӏa chӍ đoҥn, đó là đӏa chӍ byte nhӟ thҩp nhҩt trong đoҥn nhӟ. Hai đoҥn nhӟ liӅn kӅ nhau nhҩt thiӃt phҧi cách nhau 16 byte, do đó các đoҥn có đӏa chӍ là bӝi sӕ 16 cӫa nhau. Như vұy chương trình có thӇ chӭa các đoҥn tách rӡi, phӫ lҩp hoһc chӗng lên nhau. Bên trong đoҥn có đӏa 7
  • 8.
    chӍ offset đӇchӍ khoҧng cách tӯ đӏa chӍ thҩp nhҩt trong đoҥn tӟi ô nhӟ đó. Giá trӏ offset cho phép xác đӏnh chính xác đӏa chӍ logic cӫa byte nhӟ trong đoҥn đó. Như vұy, mӝt byte nhӟ đưӧc đӏnh đӏa chӍ logic bӣi mӝt cһp 2 thanh ghi 16 bit là chӭa đӏa chӍ đoҥn và đӏa chӍ đӝ lӋch (segment:offset). Ngưӡi lұp trình chӍ quan tâm tӟi đӏa chӍ logic nhưng khi truy xuҩt bӝ nhӟ, đơn vӏ ghép nӕi Bus BIU trong VXL sӁ tính tӯ đó ra đӏa chӍ vұt lý thұt sӵ cӫa byte nhӟ cҫn truy cұp theo công thӭc: Đ͓a ch͑ v̵t lý=đ͓a ch͑ đo̩n ×16 + đ͓a ch͑ đ͡ l͏ch (segment×16 + offset) ĐiӅu này đưӧc BIU thӵc hiӋn dӉ dàng bҵng cách dӏch trái giá trӏ thanh ghi chӭa đӏa chӍ đoҥn đi 4 bit rӗi cӝng vӟi giá trӏ offset trong thanh ghi chӭa đӝ lӋch (vì khi mӝt sӕ nhӏ phân đưӧc dӏch trái đi 4 digit, tương đương vӟi viӋc nhân nó vӟi 24 = 16). Vì mӛi thanh ghi đoҥn dài 16 bit nên có thӇ đӏnh đӃn 64 k đoҥn nhӟ, và sӕ đӏa chӍ offset (tương ӭng vӟi kích thưӟc mӛi đoҥn) sӁ là 64 kbyte. Do đó không gian đӏa chӍ logic sӁ lӟn hơn và bҵng 64 kbyte × 64 kbyte đӏa chӍ = 4 Gbyte nhӟ. 1.2.2.2. Các thanh ghi trong 8086 8086 có 14 thanh ghi 16 bit. Các thanh ghi đa năng AX, BX, CX, DX. Chúng đưӧc dùng đӇ lưu trӳ dӳ liӋu tҥm thӡi trong khi thӵc hiӋn chương trình. Ưu điӇm cӫa viӋc sӱ dөng thanh ghi bên trong cho viӋc lưu trӳ tҥm thӡi dӳ liӋu là cho phép VXL có thӇ truy cұp dӳ liӋu nhanh hơn rҩt nhiӅu so vӟi viӋc phҧi truy cұp bӝ nhӟ ngoài. Các thanh ghi này đưӧc tách thành hai phҫn, mӛi phҫn 8 bit, phҫn chӭa 8 bit cao là AH, BH, CH, DH và phҫn chӭa 8 bit thҩp là AL, BL, CL , DL. Mӛi phҫn đӅu có thӇ đưӧc đӏa chӍ hóa tách biӋt. y Thanh ghi AX: Thanh ghi tích lũy (Accumulator Register) ± là thanh ghi đóng vai trò trung tâm đӕi vӟi phép nhân và phép chia. Thanh ghi AH thưӡng đưӧc sӱ dөng đӇ truy nhұp qua mӝt kênh vào/ra. y Thanh ghi BX: Thanh ghi cơ sӣ (Base Register) ± đưӧc dùng cho các loҥi đӏnh đӏa chӍ đһc biӋt đӇ tính toán đӏa chӍ, thưӡng đưӧc dùng đӇ chӭa con trӓ trӓ tӟi bӝ nhӟ. y Thanh ghi CX: Thanh ghi đӃm (Count Register) ± chӭa sӕ đӃm trong các lӋnh lһp vòng. y Thanh ghi DX: Thanh ghi dӳ liӋu (Data Register) ± là thanh ghi mӣ rӝng cӫa thanh ghi AX trong các lӋnh nhân và chia. Thanh ghi này chӭa nӱa cao cӫa mӝt tích 32 bit hoһc nӱa cao cӫa mӝt sӕ bӏ chia 32 bit. Trong 8
  • 9.
    viӋc thӵc hiӋncác lӋnh đӑc/viӃt các cәng vào/ra, thanh ghi này đưӧc dùng đӇ chӭa đӏa chӍ cӫa các cәng cҫn đӑc/viӃt có giá trӏ lӟn hơn FFh. Các thanh ghi đoҥn CS, DS, SS, ES: có 4 thanh ghi đoҥn dùng đӇ lưu trӳ đӏa chӍ 16 bit cӫa 4 loҥi đoҥn nhӟ logic: đoҥn mã lӋnh CS, đoҥn dӳ liӋu DS, đoҥn ngăn xӃp SS, đoҥn phө ES. Ngăn xӃp (stack) là mӝt vùng nhӟ đưӧc đһt ra ngoài đӇ lưu trӳ đӏa chӍ và dӳ liӋu trong khi thӵc hiӋn chương trình con. y Thanh ghi đoҥn mã lӋnh CS: là thanh ghi chӭa đӏa chӍ đoҥn cӫa vùng chӭa mã lӋnh cӫa chương trình đang thӵc hiӋn. y Thanh ghi đoҥn dӳ liӋu DS: là thanh ghi đӏa chӭa đӏa chӍ đoҥn cӫa vùng dӳ liӋu mà chương trình đang thӵc hiӋn sӱ dөng, vùng này thưӡng chӭa các biӃn cӫa chương trình. y Thanh ghi đoҥn ngăn xӃp SS: là thanh ghi chӭa đӏa chӍ đoҥn bӝ nhӟ ngăn xӃp (stack) cӫa chương trình. y Thanh ghi đoҥn phө (mӣ rӝng, bә xung): là thanh ghi chӭa đӏa chӍ đoҥn cӫa vùng nhӟ bә xung mà chương trình đang sӱ dөng, vùng này cũng thưӡng chӭa các biӃn cӫa chương trình. Các thanh ghi con trӓ và chӍ sӕ: gӗm có các thanh ghi: BP, SP, SI, DI, IP. y SP (Stack Pointer) ± thanh ghi con trӓ stack: nó luôn kӃt hӧp vӟi SS đӇ chӍ ra đӍnh tӭc thӡi cӫa ngăn xӃp. Sau mӛi thao tác cҩt mӝt tӯ (word) vào ngăn xӃp SP sӁ tӵ đӝng giҧm đi 2 đơn vӏ, và ngưӧc lҥi sau mӛi thao tác lҩy mӝt tӯ ra khӓi ngăn xӃp SP sӁ tӵ đӝng tăng lên 2 đơn vӏ. y BP (Base Stack Pointer) ± thanh ghi con trӓ cơ sӣ: là thanh ghi con trӓ đӇ đánh dҩu ngăn xӃp, Trong nhiӅu thao tác vӟi stack cҫn sӱ dөng thêm thanh ghi này, chҷng hҥn như truyӅn thông sӕ thông qua stack. y SI (Source Index) và DI (Destination Index) ± thanh ghi con trӓ chӍ sӕ nguӗn và thanh ghi con trӓ chӍ sӕ đích: đưӧc thiӃt kӃ đӇ chuyên sӱ dөng trong các thao tác vұn chuyӇn dӳ liӋu. Trong mӝt sӕ lӋnh cӫa 8086 các thanh ghi này luôn đưӧc kӃt hӧp vӟi các thanh ghi đoҥn DS, ES đӇ trӓ tӟi nguӗn và đích cӫa thao tác vұn chuyӇn dӳ liӋu. Đó là cҳp DS: SI và ES:DI. Thanh ghi con trӓ lӋnh IP (Intruction Pointer): Thanh ghi con trӓ lӋnh luôn chӭa đӏa chӍ lӋch cӫa lӋnh tiӃp theo sӁ đưӧc thi hành trong đoҥn nhӟ CS. Sau khi mӝt lӋnh đưӧc thi hành thì IP lҥi đưӧc bӝ VXL thay đәi giá trӏ đӇ trӓ tӟi lӋnh tiӃp theo sӁ đưӧc thi hành. 9
  • 10.
    Thanh ghi cӡFlag (Flags Register): đây là thanh ghi 16 bit, trong đó mӛi bit đưӧc sӱ dөng đӇ thӇ hiӋn mӝt trҥng thái cӫa bӝ VXL tҥi mӝt thӡi điӇm nhҩt đӏnh trong quá trình thӵc hiӋn chương trình, trong VXL 8086 mӟi chӍ có 9 bit đưӧc sӱ dөng, ngưӡi ta gӑi mӛi bit đó là mӝt cӡ, mӛi cӡ thưӡng đưӧc biӇu diӉn bҵng mӝt kí hiӋu gӧi nhӟ, mӛi cӡ đӅu có hai trҥng thái khác nhau là 0 và 1. Ngưӡi lұp trình ASM hay dùng trҥng thái các bit cӡ làm điӅu kiӋn cho các lӋnh nhҧy có điӅu kiӋn. x x x x O D I T S Z x A x P x C x: không đưӧc đӏnh nghĩa. y C hoһc CT (Carry flag): cӡ nhӟ. CF = 1 khi sӕ nhӟ tràn khӓi bit có trӑng sӕ lӟn nhҩt. y P hoһc PF (Parity flag): cӡ parity. PF phҧn ánh tính chҹn lҿ (parity) cӫa tәng sӕ bit có trong kӃt quҧ. PF = 1 khi tәng sӕ bit 1 trong kӃt quҧ là chҹn. y A hoһc AF (Auxiliary carry flag): cӡ nhӟ phө, rҩt có ý nghĩa khi ta làm viӋc vӟi các sӕ BCD. AF = 1 khi có nhӟ hoһc mưӧn tӯ mӝt sӕ BCD thҩp (4 bit thҩp) sang mӝt sӕ BCD cao (4 bit cao). y Z hoһc ZF ( Zero flag): cӡ rӛng, ZF = 1 khi kӃt quҧ bҵng 0. y S hoһc SF (Sign flag): cӡ dҩu, SF = 1 khi kӃt quҧ âm. y hoһc OF (Overflow flag): cӡ tràn, OF = 1 khi có hiӋn tưӧng tràn sӕ hӑc, đó là trưӡng hӧp sӕ quá lӟn vưӧt ra khӓi dung lưӧng nơi gӱi đӃn. y T hoһc TF (Trap flag): cӡ bүy, TF = 1 thì CPU làm viӋc ӣ chӃ đӝ chҥy tӯng lӋnh( chӃ đӝ này cҫn dùng khi cҫn tìm lӛi trong mӝt chương trình). y I hoһc IF (Interrupt enable flag): cӡ cho phép ngҳt, IF = 1 thì CPU cho phép các yêu cҫu ngҳt đưӧc tác đӝng. y D hoһc DF (Direction flag): cӡ hưӟng, DF = 1 khi CPU làm viӋc vӟi chuӛi kí tӵ theo thӭ tӵ tӯ trái sang phҧi (hay còn gӑi D là cӡ lùi). 1.2.3. Các mode đӏa chӍ cӫa 8086 Hay còn gӑi là các chӃ đӝ đӏa chӍ, các phương pháp xác đӏnh đӏa chӍ cӫa các toán hҥng có trong lӋnh. Lưu ý rҵng tұp các thanh ghi cӫa bӝ xӱ lý đưӧc sҳp xӃp cũng tҥo nên mӝt bӝ nhӟ tӕc đӝ cao và cũng có mӝt không gian đӏa chӍ. 10
  • 11.
    Đӏa chӍ hiӋudөng EA ~ offset hay đӝ lӋch cӫa ô nhӟ chӭa toán hҥng mong muӕn tính tӯ đӏa chӍ cơ sӣ đoҥn. Đӏa chӍ vұt lý cӫa ô nhӟ chӭa toán hҥng đưӧc 8086 xác đӏnh bҵng cách cӝng đӏa chӍ hiӋu dөng vӟi đӏa chӍ cơ sӣ đoҥn nҵm trong các thanh ghi đoҥn. Thanh ghi đoҥn thông dөng nhҩt là thanh ghi DS. 8086 có các mode đӏa chӍ sau: y Đӏnh đӏa chӍ tӭc thӡi: các đơn giҧn nhҩt đӇ xác đӏnh mӝt toán hҥng là phҫn đӏa chӍ cӫa lӋnh chӭa chính toán hҥng đó chӭ không cҫn đӏa chӍ hoһc thông tin khác mô tҧ toán hҥng đó ӣ đâu. Mӝt toán hҥng như vұy gӑi là toán hҥng tӭc thӡi bӣi vì toán hҥng đưӧc tìm và nҥp tӵ đӝng tӯ bӝ nhӟ cùng lúc vӟi lӋnh và đưӧc sӱ dөng ngay lұp tӭc. Đӏnh đӏa chӍ tӭc thӡi có ưu điӇm là không cҫn mӝt truy xuҩt bӝ nhӟ nào. Tuy nhiên nó có nhưӧc điӇm là toán hҥng bӏ giӟi hҥn bӣi mӝt sӕ chӍ đһt vӯa trong trưӡng đӏa chӍ. Thí dө: MOV CX, 437Bh y Đӏnh đӏa chӍ trӵc tiӃp: phương pháp này xác đӏnh mӝt toán hҥng bҵng cách cung cҩp đӏa chӍ cӫa tӯ nhӟ chӭa toán hҥng cho bӝ xӱ lý. Vӟi chӃ đӝ đӏnh đӏa chӍ bӝ nhӟ đơn giҧn nhҩt, đӏa chӍ hiӋu dөng chӍ là sӕ 16 bit đưӧc viӃt tiӃp trong câu lӋnh. Thí dө: MOV BL, [437Ah], nҥp nӝi dung ô nhӟ có đӝ lӋch tính tӯ đӏa chӍ cơ sӣ đoҥn là 437A vào thanh ghi BL. Khi đó VXL sӁ tính toán đӏa chӍ cӫa ô nhӟ bҵng cách cӝng thêm đӏa chӍ hiӋu dөng 437A vào đӏa chӍ cơ sӣ đoҥn dӳ liӋu. ChӃ đӝ đӏnh đӏa chӍ này đưӧc gӑi là trӵc tiӃp vì đӝ dӏch chuyӇn cӫa toán hҥng đưӧc chӍ ra trӵc tiӃp trong câu lӋnh. Thí dө khác: MOV BX, [437Ah], copy mӝt tӯ 16 bit tӯ ô nhӟ vào thanh ghi BX. Bӣi mӛi đӏa chӍ trong 8086 đҥi diӋn cho 1 byte, do đó nӝi dung cӫa ô nhӟ có đӏa chӍ lӋch so vӟi đӏa chӍ đoҥn dӳ liӋu DS là 437A sӁ đưӧc copy vào thanh ghi BL, nӝi dung ô nhӟ có đӏa chӍ lӋch 437B sӁ đưӧc copy vào thanh ghi BH. Ngoài ra đӏnh đӏa chӍ trӵc tiӃp còn đưӧc dùng đӇ xác đӏnh toán hҥng đích trong bӝ nhӟ, ví dө: MOV [437Ah], BX sӁ copy vào ô nhӟ có đӏa chӍ lӋch 437A nӝi dung thanh ghi BL, và copy nӝi dung thanh ghi BH vào ô nhӟ có đӏa chӍ lӋch là 437B. y Đӏnh đӏa chӍ thanh ghi: Trong chӃ đӝ này, thanh ghi sӁ là toán hҥng nguӗn cӫa câu lӋnh. Thí dө: MOV CX, AX. Trong đó, toán hҥng nguӗn là toán hҥng đӭng sau dҩu phҭy, toán hҥng đích là toán hҥng 11
  • 12.
    đӭng trưӟc dҩuphҭy, lӋnh MOV CX, AX sӁ copy nӝi dung thanh ghi AX vào thanh ghi CX. Ta có thӇ copy nӝi dung bҩt cӭ thanh ghi 16 bit nào sang thanh ghi 16 bit khác, cũng có thӇ copy nӝi dung bҩt cӭ thanh ghi 8 bit nào sang thanh ghi 8 bit khác, các trưӡng hӧp còn lҥi là không thӇ. y Đӏnh đӏa chӍ gián tiӃp: trong chӃ đӝ này, trưӡng đӏa chӍ cho biӃt tӯ nhӟ nào hoһc thanh ghi nào chӭa đӏa chӍ cӫa toán hҥng. Trong nhóm này có các loҥi như sau: - Đӏnh vӏ gián tiӃp thanh ghi: lúc này đӏa chӍ hiӋu dөng nҵm ӣ mӝt trong các thanh ghi BX, BP, SI hoһc DI. Thí dө: MOV AX, [SI] ; chuyӇn nӝi dung cӫa ô nhӟ trong đoҥn hiӋn tҥi có offset là nӝi dung cӫa thanh ghi SI và thanh ghi AX. - Đӏnh vӏ cơ sӣ: EA là tәng cӫa đӝ dӏch chuyӇn và nӝi dung cӫa thanh ghi BX hoһc BP. -Thí dө: MOV [BX] + displacement, AL; chuyӇn nӝi dung cӫa thanh ghi AL vào ô nhӟ có đӏa chӍ offset bҵng tәng nӝi dung cӫa BX vӟi đӝ dӏch chuyӇn. y Đӏnh vӏ chӍ sӕ (indexed addressing): EA là tәng cӫa đӝ dӏch chuyӇn và nӝi dung cӫa thanh ghi SL hoһc DI. Lý do có chӃ đӝ này như sau. NhiӅu thuұt toàn cҫn thӵc hiӋn mӝt thao tác nào đó trên mӝt chuӛi cҩu trúc dӳ liӋu lưu giӳ trong nhӳng vӏ trí nhӟ liên tiӃp. Thí dө xét mӝt khӕi gӗm n tӯ lӋnh máy chiӃm các vӏ trí A, A + 1, A + 2, «, A + n-1. Các tӯ này cҫn đưӧc di chuyӇn đӃn các vӏ trí B, B + 1, B + 2, « ,B + n-1. Trong trưӡng hӧp này có thӇ thӵc hiӋn lӋnh MOV A, B rӗi thay đәi chính lӋnh đó thành MOVE A + 1, B + 1 và lһp lҥi cho tӟi khi cҧ n tӯ đưӧc sao chép hӃt. Bҵng cách đӏnh đӏa chӍ gián tiӃp có thӇ thӵc hiӋn đưӧc điӅu này. Mӝt thanh ghi hoһc tӯ nhӟ đưӧc nҥp đӏa chӍ A, mӝt thanh ghi hoһc tӯ nhӟ khác đưӧc nҥp đӏa chӍ B. LӋnh MOV dùng 2 thanh ghi này làm các con trӓ và sau mӛi lҫn sao chép mӝt tӯ con trӓ đưӧc tăng lên 1. Các con trӓ là mӝt phҫn cӫa dӳ liӋu chӭ không phҧi là phҫn cӫa chương trình và nhӳng ngưӡi sӱ dөng không đưӧc dùng chung đӗng thӡi. Mӝt giҧi pháp khác là có mӝt sӕ thanh ghi gӑi là thanh ghi ch͑ s͙ hoҥt đӝng như sau. Đӏa chӍ có 2 phҫn: sӕ cӫa mӝt thanh ghi chӍ sӕ và mӝt hҵng sӕ. Đӏa chӍ cӫa toán hҥng là tәng cӫa hҵng sӕ vӟi nӝi dung cӫa thanh ghi chӍ sӕ. Trong thí dө này, nӃu cҧ hai đӏa chӍ đưӧc đӏnh chӍ sӕ bҵng cách dùng mӝt thanh 12
  • 13.
    ghi chӍ sӕchӭa sӕ nguyên k, lӋnh MOV A, B sӁ chuyӇn nӝi dung vө trí nhӟ A + k tӟi B + k. Bҵng cách khӣi đӝng thanh ghi chӍ sӕ là 0 và tăng nӝi dung thanh ghi này lên mӝt lưӧng bҵng kích thích cӫa tӯ sau khi sao chép mӝt tӯ, chӍ cҫn mӝt thanh ghi cho vòng lһp sao chép. Hơn nӳa viӋc tăng thanh ghi sӁ nhanh hơn viӋc tăng mӝt vӏ trí nhӟ. ViӋc đánh chӍ sӕ đưӧc sӱ dөng rӝng rãi đӇ đӏnh đӏa chӍ mӝt trưӡng tҥi mӝt khoҧng cách đã biӃt tính tӯ điӇm đҫu cӫa mӝt cҩu trúc dӳ liӋu đã cho. Các biӃn cөc bӝ trong mӝt thӫ tөc đưӧc truy cұp theo cách này. ViӋc tăng hoһc giҧm giá trӏ thanh ghi chӍ sӕ trưӟc hoһc sau khi nó đưӧc sӱ dөng là viӋc làm thưӡng xuyên xҧy ra. Vì vұy ngưӡi ta thưӡng đưa các lӋnh đӏnh đӏa chӍ đһc biӋt hoһc thұm chí có nhӳng thanh ghi chӍ sӕ đһc biӋt mà tӵ chúng có thӇ tăng hoһc giҧm giá trӏ. ViӋc sӱa đәi tӵ đӝng mӝt thanh ghi chӍ sӕ đưӧc gӑi là đánh ch͑ s͙ t͹ đ͡ng (autoindexing). Thí dө lӋnh: MOV AL, [SI] + displacement; chuyӇn nӝi dung ô nhӟ có đӏa chӍ offset bҵng tәng cӫa nӝi dung SI vӟi đӝ dӏch chuyӇn vào thanh ghi AL. MOV AH,[BX] [SI] + displacement; chuyӇn nӝi dung cӫa ô nhӟ có đӏa chӍ offset bҵng tәng cӫa đӝ dӏch chuyӇn vӟi nӝi dung cӫa BX và SI vào thanh ghi AH. Đây là kiӇu đ͓nh đ͓a ch͑ ch͑ s͙ và cơ sͧ, EA là tәng cӫa nӝi dung thanh ghi cơ sӣ, thanh ghi chӍ sӕ và đӝ dӏch chuyӇn. y Đӏnh đӏa chӍ ngăn xӃp (stack addressing): Ngăn xӃp gӗm các phҫn tӱ dӳ liӋu (tӯ, kí tӵ, bit v.v«) đưӧc lưu trӳ theo mӝt trұt tӵ liên tiӃp trong bӝ nhӟ. Phҫn tӱ đҫu tiên đưӧc cҩt vào ngăn xӃp sӁ ӣ đáy ngăn xӃp. Phҫn tӱ mӟi nhҩt đưӧc cҩt vào sӁ ӣ đӍnh ngăn xӃp. KӃt hӧp vӟi mӛi ngăn xӃp là mӝt thanh ghi hoһc tӯ nhӟ chӭa đӏa chӍ cӫa đӍnh ngăn xӃp đưӧc gӑi là con tr͗ ngăn x͇p (stack pointer). Máy tính có lӋnh PUSH cҩt các nӝi dung cӫa ô nhӟ hoһc thanh ghi vào ngăn xӃp. LӋnh này phҧi thӵc hiӋn viӋc sao chép phҫn tӱ đó và tăng con trӓ ngăn xӃp. Ngưӧc lҥi, lӋnh POP lҩy nӝi dung đӍnh ngăn xӃp đưa trӣ lҥi thanh ghi hoһc ô nhӟ phҧi thӵc hiӋn sao chép mӟi vào nơi thích hӧp và giҧm con trӓ ngăn xӃp. Thí dө lӋnh: PUSH AX ;cҩt nӝi dung cӫa thanh ghi AX vào ngăn xӃp 13
  • 14.
    POP AX ;hӗi phөc giá trӏ thanh ghi AX tӯ nӝi dung đӍnh ngăn xӃp. Mӝt sӕ lӋnh không đӏa chӍ cũng có thӇ đưӧc sӱ dөng cùng vӟi ngăn xӃp. Đӏnh dҥng lӋnh này chӍ ra rҵng 2 toán hҥng đưӧc lҩy ra khӓi ngăn xӃp, toán hҥng này tiӃp sau toán hҥng kia, phép toán đưӧc thӵc hiӋn (thí dө nhân hoһc AND) và kӃt quҧ đưӧc cҩt trӣ lҥi ngăn xӃp. 1.3. Ngҳt Ngҳt (interrupt) là khҧ năng dӯng chương trình chính đang chҥy đӇ thӵc hiӋn mӝt chương trình khác rӗi sau đó lҥi quay vӅ thӵc hiӋn tiӃp chương trình chính. Mӝt trong nhӳng tình huӕng xҧy ra ngҳt như sau: trong khi vi xӱ lý đang thӵc hiӋn chuӛi lӋnh cӫa chương trình chính nӃu mӝt thiӃt bӏ ngoҥi vi nào đó cҫn trao đәi thông tin vơi vi xӱ lý, nó sӁ gӱi mӝt tín hiӋu yêu cҫu gӑi là yêu c̯u ng̷t (thí dө INTR) tӟi vi xӱ lý. Vi xӱ lý sӁ thӵc hiӋn nӕt lӋnh hiӋn tҥi và trҧ lӡi bҵng tín hiӋu ch̭p nh̵n ng̷t (thí dө INTA). Chương trình chính lúc này sӁ bӏ dӯng lҥi (ngҳt) và vi xӱ lý cҩt giӳ nӝi dung cӫa các thanh ghi đang dùng bҵng lӋnh PUSH vào mӝt vùng nhӟ đһc biӋt (gӑi là ngăn xӃp) rӗi chuyӇn sang chương trình con phͭc vͭ ng̷t tӭc là chương trình trao đәi thông tin mà đơn vӏ yêu cҫu. Sau khi xong viӋc, nhӡ lӋnh RET và các lӋnh POP hӗi phөc ngăn xӃp, vi xӱ lý sӁ quay vӅ đúng chӛ bӏ ngҳt và tiӃp tөc thӵc hiӋn chương trình chính như hình 2.10 chӍ ra. Các ngҳt không chӍ có ý nghĩa quan trӑng đӕi vӟi phҫn mӅm mà cҧ vӟi phҫn cӭng. Các ngҳt trong hӑ vi xӱ lý 80x86 có thӇ đưӧc phát ra tӯ mӝt trong ba nguӗn sau: Ng̷t cͱng: do tín hiӋu đưӧc sinh ra bӣi các chip điӋn tӱ hoһc thiӃt bӏ ngoҥi vi bên ngoài vi xӱ lí gây nên. Đó là mӝt cơ cҩu đơn giҧn và hiӋu quҧ cho phép vi xӱ lý phҧn ӭng mӝt cách kӏp thӡi vӟi các yêu cҫu ngҳt. Thí dө, ҩn hay nhҧ bàn phím sӁ gây nên ngҳt cӭng sӕ 9 (ngҳt bàn phím), chương trình xӱ lí ngҳt sӁ phҧn ӭng bҵng cách đưa kí tӵ đưӧc ҩn vào vùng đӋm cӫa bàn phím, vào vӏ trí ngay sau kí tӵ đưӧc ҩn lҫn trưӟc. Ng̷t có th͋ b͓ che (maskable) do tín hiӋu yêu cҫu ngҳt đưӧc đưa tӟi chân INTR cӫa vi xӱ lý. Ngҳt này sӁ bӏ vô hiӋu hóa (bӏ che) bҵng lӋnh hӧp ngӳ CLI (xóa cӡ ngҳt). NӃu bӏ che thì mһc dù đưӧc gӑi, chương trình xӱ lí ngҳt tương ӭng cũng không đưӧc thӵc hiӋn. LӋnh STI (đһt cӡ ngҳt) cho phép các ngҳt bӏ che trӣ lҥi hoҥt đӝng. 14
  • 15.
    Ng̷t không th͋b͓ che (non-maskable) do tín hiӋu yêu cҫu ngҳt đưӧc đưa tӟi chân NMI cӫa vi xӱ lý. Ngҳt luôn đưӧc thӵc hiӋn kӇ cҧ khi đưӧc gӑi ngay sau lӋnh CLI. Ngҳt này liên quan tӟi các hӓng hóc phҫn cӭng nghiêm trӑng (thí dө, hӓng RAM). Ng̷t m͉m: vӟi nguӗn gây ngҳt là các câu lӋnh gӑi ngҳt INT đưӧc sӱ dөng cùng sӕ thӭ tӵ ngҳt. Thí dө, lӋnh gӑi ngҳt sӕ 5 (in trang màn hình) đưӧc viӃt là INT 5. Các ngҳt mӅm cho phép gӑi các chương trình phө cӫa hӋ điӅu hành. Ngҳt mӅm còn có thӇ đưӧc gӑi tӯ ngôn ngӳ bұc cao, lúc đó nó sӁ đưӧc dӏch ra thành lӋnh hӧp ngӳ INT. Ngo̩i l͏: là nguӗn ngҳt thӭ 3 do các lӛi phát sinh trong quá trình thӵc hiӋn câu lӋnh (thí dө, ngҳt chia cho mӝt sӕ cho 0), vi xӱ lý sӁ tӵ đӝng ngҳt chương trình đang chҥy bҵng ngҳt sӕ 0. Vào cuӕi mӛi chu trình lӋnh, 8086 sӁ kiӇm tra xem có ngҳt nào đưӧc yêu cҫu không. NӃu có yêu cҫu ngҳt, 8086 sӁ phҧn ӭng theo các bưӟc sau: Giҧm con trӓ ngăn xӃp đi 2 và cҩt thanh ghi cӡ vào ngăn xӃp. Không cho phép ngҳt cӭng tӯ chân INTR bҵng cách xóa cӡ ngҳt IF trong thanh ghi cӡ. Xóa cӡ bưӟc TF trong thanh ghi cӡ. Giҧm con trӓ ngăn xӃp đi 2 và cҩt nӝi dung thanh ghi đoҥn mã vào ngăn xӃp. Giҧm con trӓ ngăn xӃp đi 2 mӝt lҫn nӳa và cҩt nӝi dung thanh ghi con trӓ lӋnh hiӋn thӡi vào ngăn xӃp. Thӵc hiӋn mӝt lӋnh nhҧy gián tiӃp far jump tӟi phҫn đҫu cӫa chương trình con phөc vө ngҳt do ngưӡi dùng viӃt. Vi xӱ lý 8086 có thӇ phөc vө đưӧc tӟi 256 ngҳt khác ngau, đưӧc đánh sӕ tӯ 0 đӃn 255. Mӛi ngҳt ӭng vӟi mӝt chương trình con phөc vө ngҳt và sӁ đưӧc thӵc hiӋn khi đưӧc gӑi lҥi. Đӏa chӍ lôgic ô nhӟ bҳt đҫu cӫa mӛi chương trình này gӑi là mӝt véctơ ng̷t dài 4 byte gӗm đӏa chӍ đoҥn và đӏa chӍ offset 16 bit, đӏa chӍ offset đưӧc đһt trưӟc đӏa chӍ đoҥn. 256 đӏa chӍ này đưӧc lưu trӳ lҫn lưӧt trong vùng nhӟ thҩp nhҩt cӫa bӝ nhӟ gӑi là b̫ng các vectơ ng̷t có đӝ dài là 4 x 256 = 1024 byte tӯ đӏa chӍ 0000: 0000 đӃn 0000: 03FF. Như vұy, đӏa chӍ cӫa chương trình xӱ lí ngҳt sӕ 0 nҵm ӣ 4 ô nhӟ tӯ 0000: 0000 đӃn 0000: 0003, đӏa chӍ cӫa chương trình ngҳt sӕ 1 tӯ 0000: 0004 đӃn 0000: 0007 v.v« Dó đó đӇ xác đӏnh ô nhӟ chӭa đӏa chӍ bҳt đҫu cӫa chương trình con phөc vө ngҳt ta chӍ viӋc nhân sӕ ngҳt vӟi 4. 15
  • 16.
    1.4. Giӟi thiӋuvӅ hӧp ngӳ 1.4.1. Lұp trình bҵng hӧp ngӳ ViӋc lұp trình bҵng ngôn ngӳ máy đòi hӓi ta phҧi nhӟ các mã lӋnh bҵng sӕ (dưӟi dҥng nhӏ phân), còn đưӧc gӑi là mã máy, phҧi sҳp đһt vӏ trí cӫa mã lӋnh và các sӕ liӋu trong bӝ nhӟ cӫa máy tính, ngay cҧ sӕ liӋu cũng phҧi viӃt dưӟi dҥng sӕ. Công viӋc này rҩt nһng nhӑc, tӕn công, dӉ nhҫm lүn và khó chӍnh sӱa. Tuy nhiên viӋc viӃt chương trình bҵng ngôn ngӳ máy cũng có nhӳng ưu điӇm cӫa nó như phát huy tӕi đa đưӧc khҧ năng cӫa tұp lӋnh cӫa bӝ vi xӱ lý, cũng như sӱ dөng có hiӋu quҧ nhҩt bӝ nhӟ cӫa máy tính, tӕc đӝ thӵc hiӋn chương trình là nhanh nhҩt và chương trình có kích thưӟc nhӓ nhҩt. ĐӇ tránh các khó khăn cӫa viӋc viӃt chương trình bҵng ngô ngӳ máy nhưng vүn đҥt đưӧc ưu điӇm cӫa viӋc lұp trình bҵng ngôn ngӳ máy ngưӡi ta sӱ dөng hӧp ngӳ. Hӧp ngӳ là mӝt ngôn ngӳ lұp trình gӧi nhӟ, nó có các ưu nhưӧc điӇm như sau: y Ưu điӇm : Vì ngôn ngӳ Assembler rҩt gҫn gũi vӟi ngôn ngӳ máy nên chương trình + Chҥy nhanh. + TiӃt kiӋm bӝ nhӟ. + Có thӇ lұp trình truy cұp qua các giao diӋn vào ra nhưng hiӋn nay các ngôn ngӳ bұc cao cũng có thӇ làm đưӧc. y Nhưӧc điӇm + Khó viӃt bӣi vì yêu cҫu ngưӡi lұp trình rҩt am hiӇu vӅ phҫn cӭng. + Khó tìm sai: bao gӗm sai vӅ cú pháp (syntax) và sai vӅ thuұt toán (Algorithm). Chương trình dӏch sӁ thông báo sai ta sӁ dùng debug cӫa DOS đӇ kiӇm tra. + Không chuyӇn chương trình Assembler cho các máy tính có cҩu trúc khác nhau. y Ӭng dөng + ViӃt lõi cӫa hӋ điӅu hành. + Các chương trình trò chơi ( ngày trưӟc). + Tҥo virus. + Các chương trình đo và điӅu khiӇn sӱ dөng trong công nghiӋp, ngày nay các vi điӅu khiӇn đưӧc sӱ dөng mӝt cách rӝng rãi. 1.4.2. HӋ lӋnh Assembler a) HӋ lӋnh assembler gӗm có: 16
  • 17.
    y Tұp lӋnhMNEMONIC sinh mã máy đӇ chҥy chương trình. y Các DIRECTIVE điӅu khiӇn khi dӏch chương trình. b) Cú pháp cӫa mӝt dòng lӋnh ASM y Mӛi mӝt dòng chӍ đưӧc viӃt mӝt lӋnh. y [Label] [Directive/Mnemonic] [Operands] [;Commnet] [Nhãn] [Loҥi lӋnh] [Toán hҥng][Ghi chú] Tӯ ; cho đӃn hӃt dòng là ghi chú và nó có hiӋu lӵc chӍ trên 1 dòng. ví dө: L1: mov ax,bx c) Tұp lӋnh Mnemonic - Tұp lӋnh Mnemonic là gì? Đó là lӋnh cӫa ASM đưӧc thӇ hiӋn bҵng viӃt tҳt cӫa tiӃng Anh cho dӉ hiӇu. Ví dө: TiӃng Anh LӋnh dҥng Mnemonic Move mov Addition add Multiplication mul Các quy ưӟc vӅ toán hҥng: y SRC: Toán hҥng nguӗn. y DST: Toán hҥng đích. y REG(reg8/reg16): Toán hҥng là thanh ghi y Data: Toán hҥng là hҵng sӕ. y Mem: Toán hҥng là biӃn nhӟ. y Segreg: Toán hҥng là thanh ghi segment. Tұp lӋnh MNEMONIC gӗm có 6 nhóm: y Nhóm 1: Các lӋnh di chuyӇn dӳ liӋu y Nhóm 2: Các lӋnh sӕ hӑc. y Nhóm 3: Các lӋnh thao tác bit y Nhóm 4: Các lӋnh thao tác xâu ký tӵ. y Nhóm 5: Các lӋnh rӁ nhánh y Nhóm 6: Các hӋ thӕng cӡ 1.4.2. Các bưӟc viӃt chương trình hӧp ngӳ HiӋn nay có hai chương trình dӏch rҩt phә biӃn là MASM (cӫa hãng Microsoft) và TASM (cӫa hãng Borland) vӅ cơ bҧn là hai chương dӏch này rҩt giӕng nhau nhưng khác nhau ӣ chӛ: khi viӃt lӋnh push NӃu viӃt : push ax 17
  • 18.
    push bx push cx thì cҧ hai chương trình đӅu biên dӏch đưӧc. ( cách viӃt này theo MASM). Còn trong TASM thì cho phép viӃt push ax bx cx 1.4.2.1. Cài đһt chương trình dӏch TASM: y Cách 1: Mua đĩa bҧn quyӅn nӃu là đĩa mӅm thì có 5 đĩa hoһc là 1 đĩa CD. Hoһc download phҫn mӅm TASM hoһc MASM vӅ. Run cmd A: install y Cách 2: + Tҥo thư mөc: C:TASM + Copy 4 tӋp lõi tӯ máy khác đã cài đһt theo cách 1 vӅ thư mөc đã tҥo trưӟc. 1.4.2.2. Các bưӟc thӵc hiӋn mӝt chương trình Assember trên máy PC : (soҥn thҧo chương trình, dӏch chương trình, liên kӃt, chҥy thӱ và cách tìm sai bҵng DEBUG cӫa DOS và TD (Turbo Debug) cӫa Borland) Bao gӗm 4 bưӟc: + Bưӟc 1: Dùng chương trình soҥn thҧo bҩt kì (Edit, NC, TC, «.) đӇ soҥn thҧo chương trình. Sau khi soҥn thҧo xong phҧi cҩt tӋp có đuôi là .ASM. + Bưӟc 2: Dӏch chương trình gӕc có đuôi .ASM thành tӋp có đuôi là .OBJ Cú pháp: C:BT> tasm ten tep[.ASM] ten tep.OBJ 18
  • 19.
    Chú ý: khichương trình dӏch có lӛi thì không sinh ra tӋp có đuôi là .OBJ Cách khai báo sai ** Error**ten tep.asm[10] Illegal Instruction dòng thӭ bao nhiêu lӛi gì + Bưӟc 3: Liên kӃt đӇ chuyӇn tên tӋp có đuôi .OBJ sang tӋp .EXE hay .COM Cú pháp: C:BT> tlink ten tep[.OBJ] ten tep.EXE hay ten tep.COM + Bưӟc 4: Chҥy thӱ chương trình Khi chҥy nӃu có lӛi thì dùng debug đӇ kiӇm tra. Ví dө: .model small .stack .data message db "Hello$" .code main proc mov ax,seg message mov ds,ax mov ah,09 lea dx,message int 21h mov ax,4ch int 21h main endp end main 1.4.3. Cҩu trúc mӝt chương trình hӧp ngӳ dҥng segment đơn giҧn Cҩu trúc cӫa mӝt chương trình hӧp ngӳ có liên quan chһt chӁ vӟi cҩu trúc phҫn cӭng cӫa bӝ vi xӱ lý. Ngưӡi ta đã tҥo dӵng bӕn đoҥn (segment) đưӧc dӵ tính cho bӝ vi xӱ lý trong quá trình lұp trình: đoҥn mã lӋnh, đoҥn dӳ liӋu, đoҥn ngăn xӃp và đoҥn mӣ rӝng. Trong đó, ít nhҩt mӝt chương trình hӧp ngӳ phҧi có mӝt đoҥn mã lӋnh. Do chương trình hӧp ngӳ có cҩu trúc như vұy mà ta có khái niӋm vӅ chương trình hͫp ngͷ d̩ng segment. Mӝt chương trình segment dҥng chuҭn phҧi đӏnh nghĩa đҫy đӫ bӕn đoҥn, mӛi đoҥn đưӧc bҳt đҫu bҵng chӍ dүn hưӟng 19
  • 20.
    (directive) segment vàkӃt thúc bҵng chӍ dүn hưӟng ENDS, mӛi đoҥn đӅu đưӧc ngưӡi lұp trình cho trưӟc mӝt tên đӝc lұp vӟi kiӇu cӫa nó. Ӣ cuӕi mӛi chương trình hӧp ngӳ có chӍ dүn hưӟng END đӇ hưӟng dүn cho bӝ dӏch hӧp ngӳ biӃt rҵng chương trình đã kӃt thúc. Tuy nhiên, viӋc viӃt mӝt chương trình hӧp ngӳ dҥng segment chuҭn quá phӭc tҥp, nên chúng ta thưӡng dùng dҥng giҧn lưӧc cӫa nó hay chương trình hͫp ngͷ d̩ng segment đơn gi̫n. 1.4.3.1. Dҥng thưӡng thҩy 1 chương trình ASM đơn giҧn (Khai báo theo directive điӅu khiӇn segment dҥng đơn giҧn) .MODEL .STACK .DATA Khai báo biӃn .CODE Nhãn chương trình: Thân chương trình END Nhãn chương trình Mӝt chương trình asm đưӧc biên dӏch thành công sӁ trӣ thành mӝt file chҥy có phҫn mӣ rӝng là .com hoһc .exe. Sӵ khác nhau cӫa chương trình dҥng .com và chương trình dҥng .exe là: y Chương trình dҥng .com có tҩt cҧ các phҫn mã lӋnh, dӳ liӋu và ngăn xӃp đӅu cùng nҵm trong mӝt segment y Chương trình dҥng .exe có phҫn mã lӋnh, dӳ liӋu và ngăn xӃp nҵm trên các segment khác nhau. a) Cҩu trúc chương trình dҥng .Com Cҩu trúc: .MODEL SMALL .CODE org 0100h Nhãn chương trình: [JMP nhãn khác khai báo biӃn nhãn khác:] Thân chương trình int 20h [các chương trình con] 20
  • 21.
    END Nhãn chươngtrình Ví dө: ViӃt chương trình hiӋn mӝt xâu lên màn hình: .model small .code org 100h begin: jmp var str db "hello world!$" var: lea dx,str mov ah,9 int 21h mov ah,1 int 21h mov ah,4ch int 21h end begin a) Cҩu trúc chương trình dҥng .exe Cҩu trúc: .MODEL SMALL .STACK 100h .DATA Khai báo biӃn .CODE Nhãn chương trình: mov ax,@data mov ds,ax Thân chương trình mov ah,4ch int 21h END Nhãn chương trình Ví dө: Chương trình hiӋn mӝt xâu lên màn hình .model small 21
  • 22.
    .stack 100h .data str db "hello world!$" .code begin: mov ax,@data mov ds,ax lea dx,str mov ah,9 int 21h mov ah,1 int 21h mov ah,4ch int 21h end begin 1.4.3.2. Các Directve (.MODEL, .STACK, .DATA, .CODE, ...) a) Directive .MODEL Chͱc năng: Cho phép ngưӡi lұp trình xác lұp vùng nhӟ RAM thích hӧp cho chương trình. Cú pháp . Model KiӇu Tiny Code + data ” 64k Small Code ” 64k; data ” 64k Compact Code ” 64k; data • 64k Medium Code • 64k; data ” 64k Large Code • 64k; data • 64k 1 array ” 64k Huge Code • 64k; data • 64k 1 array • 64k b) Directive .STACK 22
  • 23.
    Chͱc năng: Báocho chương trình dӏch cӫa ASM biӃt xác lұp mӝt vùng nhӟ RAM cho Stack. Vӟi lӋnh điӅu khiӇn này thì DOS sӁ xác lұp đӏa chӍ đҫu cӫa ngăn xӃp và giá trӏ đó đưӧc đưa vào thanh ghi segment SS. Cú pháp: . stack đӝ dài (tính theo byte) Ví dө: . stack 100h NӃu không có khai báo . stack thì lҩy đӝ dài mһc đӏnh default. c) Directive . DATA Chͱc năng: Báo cho chương trình dӏch cӫa ASM biӃt đӇ xác lұp mӝt vùng nhӟ RAM cho dӳ liӋu chương trình. Cú pháp: .DATA Khai báo biӃn BiӃn trong ASM có ba loҥi: biӃn sӕ, biӃn xâu kí tӵ và biӃn trưӡng sӕ y Khai báo biӃn sӕ . DATA Tên_biӃn KiӇu Giá_trӏ_ban_đҫu/? Các kiӇu dӳ liӋu: db ( 1 byte) dw (2 byte) dd ( 4 byte) dp ( 6 byte) dq ( 8 byte) dt ( 10 byte) trong đó 2 biӃn db và dw hay dùng. Ví dө: .DATA Value dw ? Value db 10 y Khai báo biӃn xâu kí tӵ . DATA Tên_biӃn db Các_kí_tӵ_cách_nhau_bӣi_dҩu_phҭy đӝ_lӟn dup (1 kí tӵ/ ?) Ví dө: .DATA xau1 db µH¶,¶e¶,¶l¶,¶l¶,¶l,¶o¶ xau2 db 100h dup(µA¶) xau2 db 100 dup(?) 23
  • 24.
    y Khai báobiӃn trưӡng sӕ .DATA Tên_trưӡng_sӕ kiӇu_cӫa_thành_phҫn (Các sӕ cách nhau bӣi dҩu ',') Đӝ_lӟn dup( 1 sӕ/?) Ví dө: .DATA array1 db 100,2,21,31 array2 dw 100h dup(-100) Chú ý: NӃu chương trình có khai báo biӃn (tӭc là có .DATA) thì ngưӡi lұp trình ASM phҧi đưa phҫn đӏa chӍ segment cӫa vùng nhӟ dӳ liӋu vào trong DS nhӡ 2 lӋnh sau: mov reg16, @data mov ds,reg16 Ví dө: mov ax, @data mov ds,ax d) Directive .CODE Chͱc năng: Báo cho chương trình dӏch ASM biӃt đӇ xác lұp 1 vùng nhӟ RAM cho phҫn tӱ mã máy cӫa chương trình. Cú pháp: .CODE 1.4.4. Cҩu trúc cӫa mӝt chương trình segment dҥng chuҭn Ta có thӇ hình dung dҥng thưӡng thҩy cӫa mӝt chương trình segment như sau: Segment_Name SEGMENT .... .... .... Segment_Name ENDS END 1.4.4.1. Chương trình segment đơn giҧn dҥng chuҭn Stack segment db 100h dup (?) Stack ends Data segment Khai báo biӃn 24
  • 25.
    Data ends Code segment Assume cs:code, ds:data, ss:stack Nhan CT: mov ax, data mov ds,ax mov ah, 4ch int 21h code ends END Nhan CT 1.4.4.2. Các directive điӅu khiӇn segment: dҥng chuҭn (SEGMENT, GROUP và ASSUME) a) Directive SEGMENT Chͱc năng: báo cho chương trình dӏch ASM xác lұp các segment cho chương trình. Cú pháp: Khuân mүu đҫy đӫ cӫa chӍ dүn hưӟng SEGMENT là: Segment_Name SEGMENT Align Combine Use Class PARA(16 byte) PUBLIC USER16 Class BYTE (1 byte) COMMON USER32 WORD(2 byte) STACK DWORD(4 byte) AT PAGE(128 byte) -Segment_Name: bҩt kǤ mӝt đӏnh danh nào. Tên segment chӍ đưӧc phép bao gӗm mӝt tӯ, nӃu gӗm nhiӅu tӯ thì phҧi có dҩu gҥch dưӟi đӇ nӕi các tӯ vӟi nhau. Các phҫn tӱ đӭng sau SEGMENT đӅu là tùy chӑn. - Align Cú pháp: Align PARA (16 byte) BYTE (1 byte) WORD (2 byte) DWORD (4 byte) PAGE (128 byte) 25
  • 26.
    Chͱc năng: xáclұp khoҧng trӕng giӳa segment đang khai báo vӟi segment trưӟc nó. NӃu là BYTE thì khoҧng trӕng giӳa hai segment là 1 byte, PARA là 16 byte... hình: Xác lұp khoҧng trӕng giӳa hai segment là 1 byte (BYTE) NӃu như Align không đưӧc đӏnh nghĩa thì chӍ thӏ mһc đӏnh PARA sӁ đưӧc sӱ dөng. - Combine Chӭc năng 1: cho phép đһt segment khai báo vào mӝt vùng nhӟ RAM theo yêu cҫu. Cú pháp: tên segment SEGMENT đӏa chӍ .... .... .... Tên segment ENDS Chӭc năng 2: phөc vө chương trình đa tӋp thuҫn tuý ASM, cách gӝp các segment có cùng tên nҵm ӣ các tӋp khác nhau khi liên kӃt. Cú pháp: COMMON Tҩt cҧ các đoҥn cùng tên đưӧc nҥp chӗng lên nhau, sao cho tҩt cҧ đӅu bҳt đҫu ӣ cùng mӝt đӏa chӍ. Khi đó đoҥn tәng cӝng sӁ lӟn bҵng đoҥn riêng lҿ lӟn nhҩt PUBLIC Các đoҥn cùng tên sӁ đưӧc kӃt nӕi vӟi nhau thành mӝt đoҥn duy nhҩt. PRIVATE Mӛi đoҥn nҵm trong mӝt đoҥn vұt lý riêng. (Default) - USE : chӍ có tӯ thӃ hӋ 80386 và chӍ đưӧc dùng vӟi chӍ dүn hưӟng 386. 26
  • 27.
    use16 ASM 16bit (default): Đӝ dài đoҥn cӵc đҥi là 64Kbyte use32 ASM 32 bit : Đӝ dài đoҥn cӵc đҥi là 4Gbyte. - µCLASS¶ Chӭc năng: cho phép gӝp các segment có cùng lӟp lҥi gҫn nhau khi liên kӃt. Tên lӟp phҧi đưӧc đһt trong dҩu nháy đơn '', có thӇ dùng mӝt tên bҩt kǤ. Tҩt cҧ các segment có cùng tên nhưng có tên lӟp khác nhau sӁ đưӧc nҥp kӃ tiӃp nhau vào trong bӝ nhӟ. Thông thưӡng thì ta chӍ cҫn có mӝt tên lӟp khi ta muӕn kӃt nӕi các chương trình hӧp ngӳ vӟi các chương trình ngôn ngӳ bұc cao. Cách khai báo 3 segment cӫa chương trình: Dҥng chuҭn Dҥng đơn giҧn Stack segment db 100h dup (?) .Stack 100h Stack ends Data segment .DATA Khai báo biӃn Khai báo biӃn Data ends Chú ý: mov ax, data Chú ý: mov ax,@data mov ds, ax mov ds, ax Code segment .CODE Nhan CT: Nhan CT: Code ends ENDS Nhan CT ENDS Nhan CT b) Drective GROUP 27
  • 28.
    Chͱc năng: gӝpcác segment cùng loҥi cho dӉ dàng qui chiӃu. Cú pháp: tên nhóm GROUP tên các segment Khai báo các segment Gi̫i thích: Data1 segment M1 db ? Data1 ends Data2 segment M2 dw ? Data2 ends Code segment PS: mov ax, data1 mov ds,ax mov cl, M1 mov ax, data2 mov ds,ax mov cl, M2 Ta làm group như sau: Nhom_DL GROUP data1,data2 Data1 segment M1 db ? Data1 ends Data2 segment M2 dw ? Data2 ends Code segment PS: mov ax, nhom_DL mov cl, M1 mov dx,M2 c) Directive ASSUME Chͱc năng: cho biӃt segment khai báo thuӝc loҥi segment nào Cú pháp: assume tên thanh ghi segment : tên segment 28
  • 29.
    Gi̫i thích: assume cs:x3,ds:x2,ss:x1 Chú ý: assume thưӡng là dòng đҫu cӫa code segment Ví dө: HiӋn xâu kí tӵ "hello world !$" stack segment db 100h dup(?) ends stack data segment str db "hello world!$" ends data code segment assume ss:stack,cs:code,ds:data begin: mov ax,data mov ds,ax lea dx,str mov ah,9 int 21h mov ah,1 int 21h mov ah,4ch int 21h ends code end begin 29
  • 30.
    Chương 2. Lұptrình vӟi Debug 2.1. Tәng quan vӅ Debug 2.1.1. Đһc điӇm cӫa Debug Debug là mӝt chương trình chҥy trong môi trưӡng DOS. Nó dùng đӇ cho ngưӡi lұp trình có thӇ: y nhұp và dӏch các lӋnh dҥng hӧp ngӳ sang mã máy và ngưӧc lҥi y nҥp, xem và thay đәi nӝi dung cӫa tӋp ӣ trong khӕi nhӟ y chҥy chương trình theo tӯng lӋnh, nhóm lӋnh hay cҧ chương trình y sӱa tӯng byte, nhiӅu byte hay cҧ chương trình y xem và thay đәi nӝi dung các thanh ghi Các lӋnh cӫa debug đӅu bҳt đҫu bҵng mӝt hay hai chӳ cái, trong đó có mӝt dҩu ? 2.1.2. Khӣi đӝng và thoát khӓi Debug Khӣi đӝng Debug tҥi dҩu nhҳc cӫa DOS ta gõ lӋnh: Debug [ә đĩa][đưӡng dүn][tên tӋp] Trong đó các tham sӕ đi đҵng sau lӋnh Debug dùng đӇ chӍ ra tên tӋp .EXE hay .COM đӇ kiӇm tra. Sau khi khӣi đӝng Debug thì màn hình lúc này còn mӝt dҩu nhҳc là dҩu gҥch ngang nhӓ "_". Tҥi đây ta gõ các lӋnh cӫa Debug đӇ thӵc hiӋn kӃt thúc lӋnh là ENTER và muӕn thoát khӓi Delbug ta gõ lӋnh q (quit). 2.2. Các lӋnh cӫa Debug 2.2.1. Nhóm các lӋnh biên soҥn chương trình 1) LӋnh A Cú pháp: A [address] Thông sӕ address: là mӝt sӕ hexa gӗm 4 chӳ sӕ đӇ chӍ đӏa chӍ bҳt đҫu các lӋnh dҥng hӧp ngӳ cӫa chương trình. Đӏa chӍ có thӇ là CS:Offset hay chӍ có đӏa chӍ Offset vì ngҫm đӏnh là CS hiӋn hành. NӃu không có tham sӕ address thì lҩy đӏa chӍ CS:Offset hiӋn hành mà lӋnh trưӟc dùng tҥi đó. Công dөng: LӋnh cho ta nhұp các lӋnh cӫa chương trình dҥng hӧp ngӳ vào mӝt đӏa chӍ ô nhӟ. Ví dө: A 200 hay A 0200 Khi đó màn hình sӁ hiӋn ra đӏa chӍ ô nhӟ xxxx:0200 đӇ ta gõ lӋnh vào đӏa chӍ trên, ví dө ta gõ lӋnh MOV AX, 09 (các giá trӏ trong Debug đӅu ӣ dҥng hexa 30
  • 31.
    nên ta khôngcҫn đưa thêm ký tӵ h đҵng sau giá trӏ đó. NӃu có nó sӁ báo lӛi). Sau khi nhҩn Enter thì dòng lӋnh đưӧc: y dӏch ra mã máy y ghi vào ô nhӟ có đӏa chӍ trên y màn hình hiӋn ra đӏa chӍ tiӃp theo đӇ chӡ nhұp lӋnh tiӃp theo Cӭ tiӃp tөc như vұy ta có thӇ nhұp đưӧc cҧ chương trình 2) LӋnh E Cú pháp: E <address> [list] Thông sӕ address là mӝt sӕ hexa gӗm bӕn chӳ sӕ đӇ chӍ đӏa chӍ bҳt đҫu đӇ xem hay sӱa đәi dӳ liӋu. Đӏa chӍ có thӇ là CS:Offset hay chӍ là Offset vì ngҫm đӏnh là CS hiӋn hành. Thông sӕ list là danh sách các dӳ liӋu mà ta muӕn nhұp vào các ô nhӟ liên tiӃp. NӃu là mӝt xâu ký tӵ thì tâ phҧi đһt trong hai dҩu nháy kép "" hay hai dҩu nháy đơn ''. Công dөng: Dùng đӇ xem và sӱa nӝi dung cӫa tӯng ô nhӟ. Ta chӍ cҫn chӍ ra đӏa chӍ đҫu tiên cӫa ô nhӟ và khi đó nó sӁ hiӋn ra nӝi dung cӫa ô nhӟ đҫu tiên, nӃu ta muӕn sӱa dӳ liӋu cӫa ô nhӟ thì ta cӭ viӋc nhұp dӳ liӋu mӟi bên cҥnh dӳ liӋu cũ, sau đó nhҩn dҩu cách đӇ xem nӝi dung cӫa ô nhӟ tiӃp theo. KӃt thúc lӋnh này là dҩu Enter. 3) LӋnh F Cú pháp: F range list Thông sӕ range xác đӏnh mӝt vùng nhӟ, có thӇ là đӏa chӍ bҳt đҫu và đӏa chӍ kӃt thúc hay đӏa chӍ bҳt đҫu và chiӅu dài cӫa vùng nhӟ. thông sӕ list chӍ danh sách các dӳ liӋu muӕn lҩp đҫy vùng nhӟ range Công dөng: Lҩp đҫy các ô nhӟ bҵng mӝt danh sách các dӳ liӋu. LӋnh này có thӇ thay cho lӋnh E đӇ nhұp đӗng thӡi nhiӅu dӳ liӋu cùng mӝt lúc. Ví dө: F 0100 L 100 41 42 43 LӋnh này sӁ ghi đҫy các ô nhӟ tӯ 0100 đӃn 01FF (100 đӏa chӍ) bҵng các con sӕ 41, 42, 43. Ba giá trӏ này sӁ lһp lҥi cho đӃn khi toàn bӝ các ô nhӟ đưӧc lҩp đҫy giá trӏ. Ví dө 2: F 0100 0120 41 42 LӋnh này sӁ lҩp đҫy các ô nhӟ trong vùng tӯ 0100 đӃn 0120 (21 ô nhӟ) bӣi các giá trӏ 41, 42. 4) LӋnh U Cú pháp: U [range] 31
  • 32.
    Thông sӕ rangexác đӏnh đӏa chӍ đҫu và đӏa chӍ cuӕi hay đӏa chӍ đҫu và chiӅu dài ô nhӟ. Công dөng: Có thӇ nói lӋnh này trái ngưӧc vӟi lӋnh A, nó dӏch ngưӧc các lӋnh tӯ mã máy sang lӋnh dҥng assembly trong các ô nhӟ đưӧc chӍ ra vùng range hay đӏa chӍ IP hiӋn hành. Ví dө: U 0100 : Dӏch ngưӧc 32 byte đҫu tiên tӯ đӏa chӍ 0100 U CS:0100 110 : Dӏch ngưӧc dӳ liӋu tӯ đӏa chӍ CS:0100 tӟi CS: 110 U 0100 L 20 : Dӏch ngưӧc 20 dòng lӋnh bҳt đҫu tӯ đӏa chӍ 0100 2.2.2. Nhóm các lӋnh dӏch chuyӇn dӳ liӋu 1) LӋnh I Cú pháp: I <đӏa chӍ cәng> Thông sӕ đӏa chӍ cәng vào có thӇ mã hóa thành 16 bit Công dөng: Đӑc giá trӏ cӫa cәng có đӏa chӍ đưӧc chӍ ra Ví dө: I 2F8 : Đӑc giá trӏ cӫa cәng có đӏa chӍ là 2F8 và in giá trӏ lên màn hình 2) LӋnh O Cú pháp: O <Đӏa chӍ cӗng> <giá trӏ> Thông sӕ đӏa chӍ cәng giӕng lӋnh I Thông sӕ giá trӏ là byte sӕ liӋu đưa ra cәng Công dөng: LӋnh này đưa mӝt byte dӳ liӋu ra cәng Ví dө: O 61 3A : Đưa giá trӏ 3A ra cәng 61 3) LӋnh L Cú pháp: Dҥng 1: L [address] ghi nӝi dung cӫa mӝt sӕ byte đã đưӧc chӍ đӏnh trong thanh ghi BX:CX cӫa mӝt tӋp lên đĩa. Dҥng 2: L address driver firstsector numer nҥp trӵc tiӃp các cung đưӧc chӍ đӏnh Thông sӕ address là đӏa chӍ mà ӣ đó ta muӕn nҥp tӋp hay nӝi dung cӫa cung. NӃu không chӍ đӏnh đӏa chӍ thì Debug sӁ lҩy đӏa chӍ mһc đӏnh trong CS. Thông sӕ Driver chӍ đӏnh ә đĩa trên đó các cung chӍ đӏnh sӁ đưӧc đӑc. Có các giá trӏ 0=ә A, 1=ә B, 2=ә C,... Thông sӕ Fistsector là mӝt sӕ hexa chӍ sӕ cung đӇ nҥp Thông sӕ number là mӝt sӕ hexa chӍ sӕ các cung liên tiӃp sӁ đưӧc đӑc. 32
  • 33.
    Công dөng: Dҥng1 nҥp nӝi dung cӫa tӋp tin có tên N vào bӝ nhӟ cӫa máy tính có đӏa chӍ là address. NӃu không có đӏa chӍ thì máy sӁ lҩy đӏa chӍ CS:0100. Cһp thanh ghi BX:CX sӁ chӭa kích thưӟc tӋp. Dҥng 2: Nҥp nӝi dung các cung trên đĩa vào bӝ nhӟ bҳt đҫu tӯ đӏa chӍ address. Sector đҫu tiên trên đĩa cҫn đưӧc xác đӏnh trong firstsector và sӕ sector cҫn đӑc đưӧc cho vào trong number. Ví dө: Nҥp tӋp a.txt vào đӏa chӍ bҳt đҫu là CS:0000h y N a.txt y L0 Ví dө: Nҥp 5 sector đҫu tiên cӫa đĩa A vào bӝ nhӟ có đӏa chӍ là DS:0000h: L DS:0000 0 1 5 4) LӋnh N Cú pháp: N [driver][đưӡng dүn]<tên tӋp> Công dөng: LӋnh này đһt tên cho tӋp sҳp ghi hay tӋp đã tӗn tҥi đӇ đӑc vào bӝ nhӟ. Ví dө: N C:test.txt R CX 100 W 0100 Hai lӋnh này sӁ ghi 100 byte bҳt đҫu tҥi đӏa chӍ 0100 vào tӋp test.txt trong ә đĩa C. 5) LӋnh W Cú pháp: Dҥng 1: W[address] Ghi nӝi dung cӫa sӕ byte đưӧc chӍ trong BX:CX bҳt đҫu tҥi address vào tӋp có tên đưӧc đһt bӣi lӋnh N Dҥng 2: W address driver firstsector number Các tham sӕ giӕng lӋnh L Ví dө: W 0000 0 200 10 : Ghi 10 sector trong bӝ nhӟ bҳt đҫu tҥi đӏa chӍ CS:0000 vào sector thӭ 200 cӫa đĩa A. 6) LӋnh M Cú pháp: M range address Thông sӕ range chӍ đӏnh các đӏa chӍ bҳt đҫu hoһc kӃt thúc hay đӏa chӍ bҳt đҫu và chiӅu dài vùng nhӟ mà ta muӕn chép nӝi dung. 33
  • 34.
    Thông sӕ addresslà đӏa chӍ bҳt đҫu mà ta muӕn chép nӝi dung cӫa vùng nhӟ range đӃn Công dөng: Chép nӝi dung cӫa vùng nhӟ range sang vùng khác có đӏa chӍ bҳt đҫu là address. Ví dө: M 0100 2FE 3000:0000 : ChuyӇn vùng dӳ liӋu tӯ DS:0100 đӃn DS:02FE sang vùng nhӟ bҳt đҫu là 3000:0000 2.2.3. Nhóm lӋnh quan sát 1) LӋnh ? LӋnh này hiӋn nӝi dung cӫa các lӋnh cӫa Debug và chӍ dүn (lӋnh HELP) 2) LӋnh R Cú pháp: R [register] LӋnh này nӃu không có tham sӕ register thì nó sӁ cho hiӋn nӝi dung tҩt cҧ các thanh ghi cӫa vi xӱ lý kӇ cҧ thanh ghi cӡ. NӃu có tham sӕ register thì lӋnh này cho hiӋn nӝi dung cӫa thanh ghi đó và cho phép thay đәi nӝi dung cӫa thanh ghi đó. 4) LӋnh D Cú pháp: D [address] hay D[range] Thông sӕ address là đӏa chӍ bҳt đҫu cӫa mӝt vùng nhӟ 128 byte đӇ hiӇn thӏ Thông sӕ range là đҥi chӍ đҫu và đӏa chӍ cuӕi hay đӏa chӍ đҫu và đӝ dài cӫa vùng nhӟ đӇ hiӇn thӏ. 5) LӋnh C Cú pháp: C range address Thông sӕ range chӍ đӏnh đӏa chӍ bҳt đҫu và kӃt thúc hay đӏa chӍ bҳt đҫu và chiӅu dài cӫa vùng nhӟ thӭ nhҩt đӇ so sánh. Thông sӕ address chӍ đӏnh đӏa chӍ bҳt đҫu cӫa vùng nhӟ thӭ hai cӫa khӕi nhӟ đӇ so sánh. Công dөng: LӋnh này sӁ so sánh hai vùng nhӟ trên nӃu giӕng nhau toàn bӝ thì Debug không hiӋn thông báo gì cҧ. Còn nӃu không đӗng nhҩt thì Debug sӁ hiӇn thӏ nӝi dung cӫa các ô nhӟ khác nhau. 2.2.4. Nhóm lӋnh thi hành chương trình 1) LӋnh T Cú pháp: T [=address][value] Thông sӕ =address chӍ đӏnh đӏa chӍ mà Debug phҧi bҳt đҫu thӵc hiӋn. NӃu không có tham sӕ này thì Debug thӵc hiӋn tӯ đӏa chӍ trong cһp CS:IP. 34
  • 35.
    Thông sӕ valuechӍ sӕ lӋnh cҫn thӵc hiӋn, giá trӏ ngҫm đӏnh là 1 Công dөng: Thӵc hiӋn tӯng lӋnh mӝt hay mӝt sӕ các lӋnh. Sau mӛi lӋnh thì nӝi dung các thanh ghi cӡ và thanh ghi chӭc năng đưӧc hiӋn lên màn hình cùng vӟi câu lӋnh tiӃp theo. 2) LӋnh P Cú pháp: P [=address][range] Thông sӕ: Các thông sӕ giӕng lӋnh T Công dөng: LӋnh này cũng thӵc hiӋn tӯng lӋnh mӝt giӕng lӋnh T chӍ có mӝt điӇm khác là khi gһp lӋnh gӑi chương trình con, lӋnh lһp hay lӋnh ngҳt thì nó thӵc hiӋn cҧ nhóm lӋnh trên. 3) LӋnh G Cú pháp: G [=address][điӇm dӯng] Thông sӕ address giӕng lӋnh T Thông sӕ điӇm dӯng chӍ đӏnh điӇm dӯng cho lӋnh G Công dөng: LӋnh này thӵc hiӋn toàn bӝ chương trình hay thӵc hiӋn tӯ đҫu đӃn điӇm dӯng. Mӝt điӅu khác biӋt so vӟi lӋnh P và T là con trӓ lӋnh IP không tăng. Ví dө: G=0100 hay G : Thӵc hiӋn toàn bӝ chương trình bҳt đҫu tҥi đӏa chӍ CS:0100 G =0100 200 : Thӵc hiӋn chương trình tӯ cs:0100 đӃn cs:0200 35
  • 36.
    Chương 3: CáclӋnh cӫa Assembly 3.1 Các lӋnh vұn chuyӇn dӳ liӋu Tҩt cҧ lӋnh trong nhóm này khi thӵc hiӋn không làm thay đәi trҥng thái cӫa các bit cӡ. 1) LӋnh mov Chͱc năng: Đưa nӝi dung tӯ SRC đӃn DST Cú pháp: mov DST, SRC reg1 reg2 mov ax, bx reg data mov cx,100 reg mem mov dx,value mem reg mov value,dx mem data mov value,100 segreg reg16 mov ds,ax reg16 segreg mov bx,cs segreg mem 16 mov cs,value mem16 segreg mov value,cs Chú ý: y Không đưӧc di chuyӇn giӳa hai biӃn nhӟ (mov mem1,mem2). Thӵc hiӋn gián tiӃp: mov reg,mem2 mov mem1,reg y Không đưa trӵc tiӃp dӳ liӋu vào thanh ghi segment (mov seg,data). Thӵc hiӋn gián tiӃp: mov reg16,data mov segreg,reg16 y Sӵ khác nhau khi sӱ dөng các chӃ đӝ đӏa chӍ ( mov ax,bx khác vӟi mov ax,[bx] ; đưa nӝi dung mà bx trӓ đӃn vào ax) mov ax,[bx] tương đương vӟi mov ax, ds:[bx] (SI,DI hay BP) 2) LӋnh push Chͱc năng: cҩt 2 byte cӫa SRC vào đӍnh ngăn xӃp(stack). Cú pháp: PUSH SRC Reg16 36
  • 37.
    Mem16 Ví dө: push ax Toán hҥng gӕc có thӇ tìm đưӧc theo các chӃ đӝ đӏa chӍ khác nhau: có thӇ là thanh ghi đa năng, thanh ghi đoҥn hay là ô nhӟ. LӋnh này thưӡng đưӧc dùng vӟi lӋnh POP như là mӝt cһp đӛi ngүu đӇ xӱ lý các dӳ liӋu và trҥng thái cӫa chương trình chính(CTC) khi vào ra chương trình con(ctc). 3) LӋnh POP Chͱc năng: lҩy 2 byte (1 tӯ) ӣ đӍnh ngăn xӃp (stack) vào toán hҥng đích. Cú pháp: POP DST Reg16 Mem16 Ví dө: push ax push bx push cx Đoҥn chương trình: Pop cx Pop bx Pop ax Chú ý: - Cơ chӃ PUSH/POP là LIPO( last in first out) - Cách viӃt trên chӍ đưӧc sӱ dөng trong MASM còn trong TASM đưӧc viӃt như sau: push ax bx cx 4) LӋnh PUSHF Chͱc năng: cҩt giá trӏ thanh ghi cӡ vào đӍnh ngăn xӃp Cú pháp: PUSHF Dӳ liӋu tҥi ngăn xӃp không thay đәi, SS không thay đәi. 5) LӋnh POPF Chͱc năng: Lҩy 2 byte tӯ đӍnh ngăn xӃp rӗi đưa vào thanh ghi cӡ. Cú pháp: POPF Sau lӋnh này dӳ liӋu tҥi ngăn xӃp không thay đәi, SS không thay đәi. 6) LӋnh XCHG (Exchange 2 Operands) Tráo nӝi dung 2 toán hҥng Chͱc năng: Tráo nӝi dung 2 toán hҥng DST và SRC Cú pháp: 37
  • 38.
    XCHG DST SRC Reg1 Reg2 Reg Mem Trong toán hҥng đích có thӇ tìm theo chӃ đӝ đӏa chӍ khác nhau nhưng phҧi chӭa dӳ liӋu có cùng đӝ dài và không đưӧc phép đӗng thӡi là 2 ô nhӟ và cũng không đưӧc là thanh ghi đoҥn. Sau lӋnh XCHG toán hҥng chӭa nӝi dung cũ cӫa toán hҥng kia và ngưӧc lҥi. LӋnh này không tác đӝng đӃn cӡ. 7) LӋnh IN Chͱc năng: đӑc dӳ liӋu tӯ cәng vào thanh ghi AL/AX Cú pháp: IN AL/AX, đӏa chӍ cәng Chú ý: + NӃu đӏa chӍ cәng <256 thì sӕ đӏa chӍ đӭng trӵc tiӃp trong lӋnh IN Ví dө: đӏa chӍ cәng là 1fh IN AL,1fh ; nӝi dung cәng 1fh đưa vào AL. + NӃu đӏa chӍ cәng • 256 thì phҧi nhӡ đӃn thanh ghi DX Ví dө: đӏa chӍ COM1 = 378h mov dx,378h in al,dx 8) LӋnh OUT Chͱc năng: đưa dӳ liӋu tӯ thanh ghi AL/AX ra cәng Cú pháp: OUT đӏa chӍ cәng,AL/AX Chú ý: y NӃu đӏa chӍ cәng <256 thì sӕ đӏa chӍ đӭng trӵc tiӃp trong lӋnh OUT Ví dө: đӏa chӍ cәng là 1fh OUT 1fh,AL ; nӝi dung cәng 1fh đưa vào AL. y NӃu đӏa chӍ cәng • 256 thì phҧi nhӡ đӃn thanh ghi DX Ví dө: đӏa chӍ COM1 = 378h mov dx,378h out dx,al LӋnh này không tác đӝng đӃn cӡ. 9) LӋnh LEA (load Efective address) Chͱc năng: lҩy phҫn đӏa chӍ offset cӫa biӃn đưa vào thanh ghi 16 bit Cú pháp: lea reg16, mem Ví dө: lea bx, Value hay mov bx, OFFSET Value Đích thưӡng là các thanh ghi: BX, CX, DX, BP, SI, DI. 38
  • 39.
    Nguӗn là tênbiӃn trong đoҥn DS đưӧc chӍ rõ trong lӋnh hay ô nhӟ cө thӇ. Ví dө: lea dx, msg; Nҥp đӏa chӍ offset cӫa bҧn tin msg vào dx. 10) LӋnh LES (Load register and ES with words from memory) Chӭc năng: chuyӇn giá trӏ cӫa 1 tӯ tӯ mӝt vùng nhӟ vào thanh ghi đích và giá trӏ cӫa tӯ tiӃp theo sau cӫa vùng nhӟ vào thanh ghi ES. Cú pháp: les reg, mem Trong đó: Đích là mӝt trong các thanh ghi AX, BX,CX, DX, SP, BP, SI, DI. Gӕc là ô nhӟ trong đoҥn DS đưӧc chӍ rõ trong lӋnh 11) LӋnh LDS (Load resgister and DS with words from memory) Chӭc năng: Nҥp mӝt tӯ tӯ bӝ nhӟ vào thanh ghi cho trong lӋnh và 1 tӯ tiӃp theo vào DS. Cú pháp: lds reg, mem 3.2 Các lӋnh sӕ hӑc 1) LӋnh ADD(addition) Chӭc năng: DST ĸDST + SRC Cӝng hai toán hҥng: lҩy toán hҥng đích cӝng vӟi toán hҥng nguӗn rӗi đưa vào toán hҥng đích. Cú pháp: 39
  • 40.
    Tác đӝng đӃncӡ: C, P, A, Z, S, O. 2) LӋnh ADC(Add with carry) Chӭc năng: cӝng có nhӟ, DSTĸ DST + SRC + CF Cú pháp: adc DST, SRC Tác đӝng đӃn cӡ: C, P, A, Z, S, O. Ví dө: adc ax, bx 3) LӋnh INC(Increment Destination Register or Memory) Chӭc năng: Tăng toán hҥng đích thêm 1. DSTĸ DST + 1 Cú pháp: inc DST Tác đӝng đӃn cӡ: C, P, Z, S, O. Ví dө: regĺ inc ax memĺ inc value 4) LӋnh INC(Increment Destination Register or Memory) Chӭc năng: Tăng toán hҥng đích thêm 1. DST ĸDST + 1 Cú pháp: inc DST Tác đӝng đӃn cӡ: C, P, Z, S, O. Ví dө: regĺ inc ax memĺ inc value 5) LӋnh SUB (Substraction) Chӭc năng: Trӯ hai toán hҥng, DSTĸ DST ± SRC Cú pháp: sub DST, SRC Ví dө: sub ax, bx Tác đӝng đӃn cӡ: C, P, A, Z, S, O. Chú ý: chӃ đӝ đӏa chӍ không đưӧc đӗng thӡi là 2 ô nhӟ hay là thanh ghi đoҥn. 6) LӋnh SBB (Substraction with borrow) Chӭc năng: Trӯ có mưӧn, DST ĸDST ± SRC ± CF Cú pháp: sbb DST, SRC Ví dө: sbb ax, bx Tác đӝng đӃn cӡ: C, P, A, Z, S, O. 40
  • 41.
    7) LӋnh MUL/IMUL (Multiply Unsigned Byte or Word/ Integer Multiplication ) Chӭc năng: Nhân 2 toán hҥng vӟi sӕ không dҩu (MUL), sӕ có dҩu (IMUL) Cú pháp: Có hai trưӡng hӧp tә chӭc phép nhân y 8 bits * 8 bits Sӕ bӏ nhân phҧi là sӕ 8 bit đӇ trong AL Sau khi nhân: al*SRC AX y 16 bits * 16 bits Sӕ bӏ nhân phҧi là sӕ 16 bit đӇ trong AX Sau khi nhân: ax*SRC dx:ax Tác đӝng đӃn cӡ: C, O. Chú ý: al = 1111 1111 bl = 0000 0010 mul bl ax = al*bl (255*2 = 510) imul bl ax = al*bl (- 1*2 = -2 ) Trong phép chia thì ax, bx, dx (al,bl,dx) là ҭn 8) LӋnh DIV/IDIV(Unsigned Divide/Integer Division) Chӭc năng: Chia hai toán hҥng vӟi sӕ không dҩu/ sӕ có dҩu Cú pháp: Hai trưӡng hӧp tә chӭc phép chia y NӃu sӕ 16 bits chia cho sӕ 8 bits y NӃu sӕ 32 bits chia cho sӕ 16 bits 41
  • 42.
    Trong phép chiathì ax, bx, dx (al,bl,dx) là ҭn Ví dө: 9) LӋnh DEC (Decrement Destination Register or Memory) Chӭc năng: Giҧm toán hҥng đích đi 1, DSTĸ DST ± 1 Cú pháp: dec DST regĺ dec ax mem ĺdec value Tác đӝng đӃn cӡ: C, P, Z, S, O. 10) LӋnh NEG (Negate a Operand) Chӭc năng: lҩy bù hai cӫa mӝt toán hҥng, đҧo dҩu cӫa mӝt toán hҥng DST ĸ - DST Cú pháp: neg DST regĺ neg ax mem ĺneg value Tác đӝng đӃn cӡ: C, P, A, Z, S, O. 11) LӋnh CMP (Compare Byte or Word) Chӭc năng: So sánh nӝi dung cӫa hai toán hҥng và dӵng cӡ. Sau khi thӵc hiӋn lӋnh này nӝi dung cӫa hai toán hҥng không thay đәi. Cú pháp: cmp DST, SRC Tác đӝng đӃn cӡ: C, P, Z, S, O. Cách dӵng cӡ: cmp DST, SRC y NӃu DST < SRC thì CF = 1. y NӃu DST • SRC thì CF = 0. y NӃu DST = SRC thì ZF = 1. y NӃu DST  SRC thì ZF = 0. 42
  • 43.
    3.3 Các lӋnhthao tác mӭc bit Chú ý: tҩt cҧ các lӋnh trong nhóm này khi thӵc hiӋn có thӇ làm thay đәi trҥng thái các bit cӡ. 1) LӋnh AND Chӭc năng: Thӵc hiӋn phép ³và logic´, bit cӫa kӃt quҧ bҵng 1 khi 2 bit tương ӭng đӅu bҵng 1. DSTĸ DST ȁ SRC Ví dө: al = 1010 1010 bl = 1100 1100 and al,bl = 1000 1000 Cú pháp: and DST, SRC Cách hay dùng: y Tách bit: al = xxxx xxxx 0001 0000 and al, 10h = 000x 0000 Khi dùng phép AND đӇ che đi/ giӳ lҥi mӝt vài bit nào đó cӫa mӝt toán hҥng thì bҵng cách nhân logic toán hҥng đó vӟi toán hҥng tӭc thì có các bit0/1 ӣ các chӛ cҫn che/ giӳ nguyên tương ӭng. y Dӵng cӡ and DST,DST Ví dө: and ax, ax NӃu ax < 0 thì SF = 1. NӃu ax • 0 thì SF = 0. NӃu ax = 0 thì ZF = 1. NӃu ax  0 thì ZF = 0. 2) LӋnh OR Chӭc năng: thӵc hiӋn phép hoһc logic, Bit cӫa kӃt quҧ = 1 khi 1 trong 2 bit là 1. DST ĸDST V SRC Ví dө: al = 1010 1010 bl = 1100 1100 or al,bl = 1110 1110 Cú pháp: or DST, SRC Tác đӝng đӃn cӡ: C = O = 0, P, Z, S. 3) LӋnh XOR 43
  • 44.
    Chӭc năng: ThӵchiӋn phép ³hoһc loҥi trӯ´ 2 toán hҥng, bit cӫa kӃt quҧ bҵng 1 khi 2 bit tương ӭng khác nhau. Ví dө: al = 1010 1010 bl = 1100 1100 xor al,bl = 0110 0110 Cú pháp: xor DST, SRC Cách hay dùng: y Tách bit: al = xxxx xxxx 0001 0000 and al, 10h = 000x 0000 Tác đӝng đӃn cӡ: C = O = 0, P, Z, S. Ví dө: Thӵc hiӋn ax = 0 1. mov ax,0 ; 3 byte 2. and ax,0 3. sub ax,ax ; 2 byte 4. xor ax,ax 4) LӋnh SHL (Shift Left) Chӭc năng: dӏch trái các bit cӫa toán hҥng đích đi mӝt sӕ lҫn nào đó (sӕ lҫn dӏch đưӧc cҩt trong thanh ghi CL). Cú pháp: SHL DST, CL (reg, mem) Tác đӝng đӃn cӡ: C, P, Z, S, O. Mӛi mӝt lҫn dӏch MSB sӁ đưa qua cӡ CF và đưa 0 vào LSB. CL chӭa sӕ lҫn dӏch mong muӕn. NӃu dӏch mӝt lҫn thì ta có thӇ viӃt trӵc tiӃp. VD: shl ax,1 NӃu sӕ lҫn dӏch • 2 thì phҧi nhӡ đӃn CL/CX shl ax, 4 Ł mov cl/cx, 4 shl ax, cl/cx Ý nghĩa: Dӏch trái 1 lҫn là nhân 2 vӟi sӕ nguyên dương. 5) LӋnh SHR (Shift Right) 44
  • 45.
    Chӭc năng: dӏchphҧi logic các bit cӫa toán hҥng đích đi mӝt sӕ lҫn nào đó (sӕ lҫn dӏch đưӧc cҩt trong thanh ghi CL). Cú pháp: SHR DST, CL (reg, mem) Tác đӝng đӃn cӡ: C, P, Z, S, O. Mӛi mӝt lҫn dӏch LSB sӁ đưa qua cӡ CF và đưa 0 vào MSB. CL chӭa sӕ lҫn dӏch mong muӕn. NӃu dӏch mӝt lҫn thì ta có thӇ viӃt trӵc tiӃp. VD: shr ax,1 NӃu sӕ lҫn dӏch • 2thì phҧi nhӡ đӃn CL/CX shr ax, 4 Ł mov cl/cx, 4 shr ax, cl/cx Ý nghĩa: Dӏch phҧi 1 lҫn là chia đôi và làm tròn dưӟi vӟi sӕ nguyên dương 6) LӋnh SAR ( Shift Arithmetically Right) Chӭc năng: dӏch phҧi sӕ hӑc các bit cӫa toán hҥng đích đi mӝt sӕ lҫn nào đó (sӕ lҫn dӏch đưӧc cҩt trong thanh ghi CL). Cú pháp: SAR DST, CL (reg, mem) Tác đӝng đӃn cӡ: C, P, Z, S, O. Mӛi mӝt lҫn MSB đưӧc giӳ lҥi ( nӃu ta hiӇu đây là bit dҩu cӫa mӝt sӕ nào đó thì dҩu luôn không đәi sau phép dӏch phҧi sӕ hӑc) còn LSB đưӧc đưa vào cӡ CF. CL chӭa sҹn sӕ lҫn dӏch mong muӕn. NӃu dӏch mӝt lҫn thì ta có thӇ viӃt trӵc tiӃp. VD:sar ax,1 NӃu sӕ lҫn dӏch • 2thì phҧi nhӡ đӃn CL/CX sar ax, 4 Ł mov cl/cx, 4 sar ax, cl/cx Ý nghĩa: Dӏch phҧi 1 lҫn là chia đôi và làm tròn dưӟi vӟi sӕ có dҩu. 7) LӋnh ROL( Rotate All Bits to the Left) 45
  • 46.
    Chӭc năng: quayvòng sang trái các bit cӫa toán hҥng đích đi mӝt sӕ lҫn nào đó (sӕ lҫn dӏch đưӧc cҩt trong thanh ghi CL). Trong mӛi lҫn quay giá trӏ bit cao nhҩt vӯa chuyӇn vào thanh ghi cӡ CF đӗng thӡi chuyӇn vào bit thҩp nhҩt Cú pháp: ROL DST, CL (reg, mem) Tác đӝng đӃn cӡ: C, O. NӃu dӏch mӝt lҫn thì ta có thӇ viӃt trӵc tiӃp. VD:rol ax,1 8) LӋnh ROR Chӭc năng: quay vòng sang phҧi các bit cӫa toán hҥng đích đi mӝt sӕ lҫn nào đó (sӕ lҫn dӏch đưӧc cҩt trong thanh ghi CL). Trong mӛi lҫn quay giá trӏ bit thҩp LSB nhҩt vӯa chuyӇn vào thanh ghi cӡ CF đӗng thӡi chuyӇn vào bit cao nhҩt MSB. Cú pháp: ROR DST, CL (reg, mem) Tác đӝng đӃn cӡ: C, O. NӃu dӏch mӝt lҫn thì ta có thӇ viӃt trӵc tiӃp. VD:ror ax,1 3.4 Các lӋnh thao tác vӟi dãy (chuӛi) Chú ý: ChӍ có 2 lӋnh trong nhóm này khi thӵc hiӋn làm thay đәi các bit cӡ. 1) LӋnh MOVSB/MOVSW (Move String Byte or String Word) Chӭc năng: ChuyӇn mӝt xâu ký tӵ theo tӯng byte(MOVSB) hay theo tӯng tӯ (MOVSW) tӯ vùng nhӟ trӓ bӣi DS:SI sang vùng nhӟ trӓ bӣi ES:DI. Sau mӛi lҫn dӏch chuyӇn thì giá trӏ cӫa SI, DI tӵ đӝng tăng lên 1 hoһc 2 khi cӡ hưӟng DF = 0 hoһc giҧm đi 1 hoһc 2 khi DF = 1. Phҫn tӱ cӫa Chuӛi đíchĸ Phҫn tӱ cӫa Chuӛi gӕc Cú pháp: MOVSB hoһc MOVSW 46
  • 47.
    Chuҭn bӏ trưӟcds:si con trӓ đӃn đҫu xâu SRC, es:di con trӓ đӃn đҫu xâu DST LӋnh này không tác đӝng đӃn cӡ. 2) LӋnh LODSB/LODSW (Load String Byte or Word into AL/AX) Chӭc năng: ChuyӇn các kí tӵ theo tӯng byte (LODSB) hay theo tӯng tӯ (LODSW) tӯ vùng nhӟ trӓ bӣi DS:SI vào AL/AX. Cú pháp: LODSB hoһc LODSW Chuҭn bӏ trưӟc ds:si con trӓ ӣ đҫu xâu, df = 0 hay df = 1. LӋnh này không tác đӝng đӃn cӡ. 3) LӋnh STOSB/STOSW (Store AL/AX in String Byte/Word) Chӭc năng: ChuyӇn các kí tӵ nҵm ӣ AL(STOSB) /AX (STOSW) vào vùng nhӟ trӓ bӣi ES:DI. Cú pháp: STOSB hoһc STOSW hoһc STOS Chuӛi đích. Xác lұp trưӟc ES:DI trӓ đӃn đҫu vùng nhӟ, df = 0 hay df = 1. LӋnh này không tác đӝng đӃn cӡ. Nhұn xét 1. movsb = lodsb + stosb 2. movsw = lodsw + stosw 4) LӋnh CMPSB/CMPSW Chӭc năng: So sánh hai xâu kí tӵ theo tӯng byte (CMPSB) / theo tӯng tӯ (CMPSW) giӳa hai vùng nhӟ trӓ bӣi DS:SI và ES:DI. LӋnh này chӍ tҥo cӡ, không lưu lҥi kӃt quҧ so sánh, sau khi so sánh các toán hҥng không bӏ thay đәi. Cú pháp: CMPSB hoһc CMPSW hoһc STOS Chuӛi đích. Xác lұp trưӟc DS:SI trӓ đӃn đҫu xâu 1, ES:DI trӓ đӃn đҫu xâu 2, df = 0 hay df = 1. Tác đӝng đӃn cӡ: ZF = 1 khi hai xâu bҵng nhau, ZF = 0 khi hai xâu khác nhau. 5) TiӅn tӕ REP (Repeat String Instruction until CX = 0). Chӭc năng: Lһp đi lһp lai lӋnh làm viӋc vӟi xâu kí tӵ đҵng sau nó cho đӃn khi cx = 0. Sau mӛi lҫn thӵc hiӋn cx tӵ đӝng giҧm đi 1 Cú pháp: mov cx, sӕ lҫn 47
  • 48.
    rep lӋnh làmviӋc vӟi xâu ; rep movsb Thuұt toán 1. DS:SI 2. ES:DI 3. D = 0 4. CX = 5 5. rep movsb; sau mӛi lҫn cx = cx ± 1 cho đӃn khi cx = 0. 3.5 Các lӋnh nhҧy ± ChuyӇn điӅu khiӇn 1) LӋnh Call Chӭc năng: Gӑi chương trình con Cú pháp 2) LӋnh RET Chӭc năng: quay vӅ chương trình đã gӑi chương trình con Cú pháp: RET (nҵm ӣ cuӕi chương trình con) 3) LӋnh INT Chӭc năng: Kích hoҥt mӝt ngҳt (chuyӇn sang chҥy chương trình con phөc vө ngҳt) (Ngҳt mӅm). Cú pháp: int n (sӕ ngҳt viӃt theo sӕ hexa) Ví du: int 21h = int 33 Các ngҳt hay dùng hӛ trӧ cho lұp trình Assembler y Hàm 1: Chӡ 1 kí tӵ mov ah,1 ; gán ah = 1 al chӭa mã ASCII ; al = 0 khi kí tӵ gõ vào là các phím chӭc năng. int 21h y Hàm 2: HiӋn 1 ký tӵ lên màn hình tӯ vӏ trí con trӓ đang đӭng. 48
  • 49.
    Cách 1: mov al, mã ASCII mov ah,0eh int 10h Cách 2: mov dl, mã ASCII ; dl = mã ASCII cӫa kí tӵ cҫn hiӇn thӏ mov ah,2 int 21h y Hàm 3: HiӋn xâu kí tӵ kӃt thúc µ$¶ lên màn hình. lea dx, tên biӃn xâu ; mov dx,offset tên biӃn xâu mov ah,9 int 21h y Hàm 4: Trӣ vӅ DOS mov ah,4ch int 21h 4) LӋnh IRET Chӭc năng: quay vӅ chương trình đã kích hoҥt nó tӯ chương trình con phөc ngҳt. Cú pháp: IRET - LӋnh JMP (go to) Chӭc năng: nhҧy không điӅu kiӋn Cú pháp: Chú ý: Bưӟc nhҧy cӫa lӋnh jump < 64k 5) LӋnh nhҧy có điӅu kiӋn Vӟi sӕ không có dҩu Vӟi sӕ có dҩu Nhҧy theo trҥng thái các (Below/above) (Less/ greater) bit cӡ Cmp DST, SRC Cmp DST, SRC Jb/jnae Nhãn KhiDST dưӟi Jl/jnge Nhãn Khi jc Nhãn Khi Đӏa chӍ SRC Đӏa chӍ DST<SRC Đӏa chӍ CF=1 Jbe/jna Nhãn Khi DST Jle/jng Nhãn Khi jnc Nhãn Khi Đӏa chӍ dưӟi SRC Đӏa chӍ DST”SRC Đӏa chӍ CF=0 hoһc = Je Nhãn Khi Je Nhãn Khi jz Nhãn Khi 49
  • 50.
    Đӏa chӍ DST= SRC Đӏa chӍ DST= SRC Đӏa chӍ ZF=1 Jne Nhãn Khi Jne Nhãn Khi jnz Nhãn Khi Đӏa chӍ DST SRC Đӏa chӍ DST SRC Đӏa chӍ ZF=0 Ja/jnbe Nhãn Khi DST trên Jg/jnle Nhãn Khi js Nhãn Khi Đӏa chӍ SRC Đӏa chӍ DST > SRC Đӏa chӍ SF=1 Jae/jnb Nhãn Khi DST trên Jge/jnl Nhãn Khi jns Nhãn Khi Đӏa chӍ /=SRC Đӏa chӍ DST •SRC Đӏa chӍ SF=0 Chú ý: Bưӟc nhҧy các lӋnh nhҧy có điӅu kiӋn phҧi nhӓ hơn hoһc bҵng 128 byte 6) LӋnh LOOP (for cӫa ASM) Chӭc năng: lһp đi lһp lҥi khӕi lӋnh ASM nҵm giӳa nhãn và loop cho đӃn khi cx = 0. Mӛi khi thӵc hiӋn mӝt vòng lһp giá trӏ cӫa CX giҧm đi 1. Cú pháp: mov cx, sӕ lҫn lһp; sӕ lҫn lһp • 1 Nhan: Khӕi lӋnh ASM Loop Nhan 3.6 Các lӋnh thao tác vӟi cӡ và điӅu khiӇn bӝ 1) LӋnh CLC (Clear CF) Chӭc năng: Xoá giá trӏ cӡ CF vӅ 0, CF = 0 Cú pháp: CLC Cӡ C = 0 2) LӋnh STC Chӭc năng: Đưa giá trӏ cӡ CF lên 1, CF = 1 Cú pháp: STC Cӡ C = 1 3) LӋnh CMC Chӭc năng: Đҧo giá trӏ hiӋn thӡi cӫa cӡ CF. Cú pháp: CMC Tác đӝng đӅn cӡ C. 4) LӋnh CLI Chӭc năng: Xoá giá trӏ cӫa cӡ IF vӅ 0(IF = 0). Cҩm toán bӝ các ngҳt cӭng trӯ ngҳt MNI. Cú pháp: CLI Cӡ IF = 0. 5) LӋnh STI Chӭc năng: Đưa giá trӏ cӫa cӡ IF lên1 (IF = 1). Cho phép ngҳt cӭng. Cú pháp: STI 50
  • 51.
    Cӡ IF =1. 6) LӋnh CLD Chӭc năng: Xoá giá trӏ cӫa cӡ DF vӅ 0 (DF = 0). Cú pháp: CLD Cӡ DF = 0, dӵng cӡ. 7) LӋnh STD Chӭc năng: Đưa giá trӏ cӫa cӡ DF lên1 (DF = 1). Cú pháp: STD Cӡ DF = 1. 8) LӋnh HLT Chӭc năng: dӯng máy Cú pháp: HLT 9) LӋnh NOP Chӭc năng: lӋnh này không thӵc hiӋn gì cҧ Cú pháp: NOP (4ȝs) Ý nghĩa: Tҥo trӉ (delay) Tҥo vòng chӡ vô tұn đӇ chӡ ngҳt. L1: nop jmp L1 51
  • 52.
    Chương 4 Chươngtrình con và chương trình đa tӋp 4.1 Thӫ tөc ± Chương trình con Trong các chương trình cӥ lӟn, viӋc module hóa đӇ cho chương trình có cҩu trúc sáng sӫa, dӉ debug và tiӃt kiӋm thӡi gian viӃt mã là mӝt viӋc hӃt sӭc quan trӑng. ĐӇ có thӇ module hóa đưӧc chương trình chúng ta cҫn phҧi sӱ dөng mӝt trong các công cө rҩt hӳu hiӋu đó là thӫ tөc ± chương trình con. Chương trình con là mӝt đoҥn các mã lӋnh đưӧc gӝp lҥi và đưӧc đһt tên, thông qua tên (bҵng cách gӑi tên), chúng ta có thӇ sӱ dөng lҥi mӝt đoҥn mã lӋnh ӣ bҩt cӭ nơi nào ta cҫn trong chương trình thay vì phҧi viӃt lҥi hoàn toàn đoҥn mã lӋnh đó. 4.1.1 Cơ chӃ làm viӋc cӫa chương trình con Nói chung cơ chӃ làm viӋc cӫa chương trình con trong ASM không khác gì nhiӅu so vӟi các ngôn ngӳ bұc cao khác. Cơ chӃ có 5 bưӟc : - Bưӟc 1: Tham sӕ thӵc đưa vào stack - Bưӟc 2: Đӏa chӍ lӋnh tiӃp theo đưa vào stack - Bưӟc 3: HӋ điӅu hành biӃt đưӧc đӏa chӍ đҫu cӫa chương trình con. Do vұy hӋ điӅu hành đưa đӏa chӍ đҫu cӫa chương trình con vào CS:IP rӁ nhánh vào chương trình con. - Bưӟc 4: Thӵc hiӋn chương trình con cho đӃn khi gһp return thì vào stack lҩy đӏa chӍ lӋnh tiӃp theo (đã cҩt ӣ bưӟc 2 đӇ đưa vào CS:IP) và quay vӅ chương trình đã gӑi nó. - Bưӟc 5: tiӃp tөc chương trình đang thӵc hiӋn dӣ. 4.1.2 Cҩu trúc cӫa chương trình con Tên chương trình con PROC [near/far] Bҧo vӋ các thanh ghi mà thân chương trình con phá vӥ. Các lӋnh ASM cӫa thân chương trình con. Hӗi phөc các thanh ghi mà thân chương trình con đã phá vӥ. RET 52
  • 53.
    Tên chương trìnhcon ENDP Nhұn xét: 1. Chương trình con thuҫn tuý ASM không có tham sӕ. 2. Vҩn đӅ near/ far - Chương trình con là near khi mã máy cӫa chương trình con và mã máy cӫa chương trình chính là cùng nҵm trong 1 segment, đӏa chӍ cӫa chương trình con và chương trình chính chӍ khác nhau phҫn đӏa chӍ offset. Cho nên đӏa chӍ lӋnh tiӃp theo cҩt váo stack chӍ cҫn 2 byte offset. - Chương trình con là far khi mã máy cӫa chương trình con và mã máy cӫa chương trình chính nҵm trên các segment khác nhau, đӏa chӍ cӫa chương trình con và chương trình chính khác nhau cҧ vӅ phҫn đӏa chӍ segment. Cho nên đӏachӍ lӋnh tiӃp theo cҩt vào stack phҧi cҫn 4 byte offset. Default: - Vӟi chương trình đưӧc khai báo directive dҥng đơn giҧn thì directive MODEL sӁ cho biӃt chương trình con là near hay far NӃu .MODEL tiny/small/compact thì chương trình con là NEAR(mã máy< 64k) NӃu .MODEL medium/large/huge thì chương trình con là FAR(mã máy>64k - Vӟi chương trình con đưӧc viӃt theo directive dҥng chuҭn thì mһc đӏnh là near. Còn muӕn chương trình con là far thì phҧi viӃt far khi viӃt chương trình con. 4.1.3 Vҩn đӅ chuyӇn giao tham sӕ Trong chương trình con cӫa hӧp ngӳ không có tham sӕ hình thӭc vì vұy mà viӋc trao đәi dӳ liӋu giӳa chương trình con và chương trình chính gӑi nó đưӧc thӵc hiӋn thông qua 3 cách sau: y ChuyӇn tham sӕ thông qua các thanh ghi: Cách này đơn giҧn và dӉ viӃt thưӡng đưӧc sӱ dөng trong các chương trình thuҫn túy ASM. Vӟi cách này ta chӍ cҫn đһt mӝt giá trӏ vào thanh ghi nào đó trong chương trình chính sau đó gӑi chương trình con và chương trình con sӁ sӱ dөng đưӧc giá trӏ trong thanh ghi đó. Nó giӕng như ta đưa các chӭc năng con vào thanh ghi AH trưӟc khi gӑi ngҳt cӫa hӋ thӕng, đó cũng là mӝt cách truyӅn tham sӕ cho chương trình con thông qua thanh ghi. 53
  • 54.
    y ChuyӇn thamsӕ thông qua các biӃn ngoài: BiӃn khai báo toàn cөc đưӧc sӱ dөng trong toàn chương trình, cҧ chương trình chính và chương trình con, do vұy ta có thӇ dùng nó đӇ chuyӇn tham sӕ. y ChuyӇn tham sӕ thông qua ngăn xӃp: Phương pháp này cҫn lưu thӭ tӵ sҳp xӃp trong ngăn xӃp đӇ truy cұp các tham sӕ. 4.1.4 Vҩn đӅ bҧo vӋ các thanh ghi ViӋc bҧo vӋ các thanh ghi trong quá trình gӑi các chương trình con là mӝt vҩn đӅ rҩt quan trӑng trong lұp trình ASM vì chương trình viӃt bҵng ASM rҩt hay dùng các toán hҥng là các thanh ghi. Do vұy trong chương trình con đôi khi có thӇ làm thay đәi giá trӏ cӫa mӝt thanh ghi nào đó làm ҧnh hưӣng tӟi kӃt quҧ thӵc hiӋn cӫa chương trình chính. Có hai phương pháp thưӡng dùng là: y Dùng lӋnh Push đӇ cҩt thanh ghi vào ngăn xӃp ӣ đҫu chương trình con và cuӕi chương trình con ta dùng lӋnh POP đӇ lҩy lҥi các giá trӏ cӫa các thanh ghi. y Dùng theo quy ưӟc: Nhӳng thanh ghi nào dùng trong chương trình chính thì không dùng trong chương trình con nӳa. Tuy nhiên cách này không hiӋu quҧ lҳm và ít dùng vì có nhӳng thanh ghi ta buӝc phҧi sӱ dөng mà không thӇ thay thӃ đưӧc. 4.1.5. Mӝt sӕ ví dө Ví dө 1: ViӃt chương trình con tính a^b. .model small add ax,tong .data mov ah,4ch tong dw 0 int 21h .stack 100h hammu proc .code push bx begin: push cx mov ax,@data mov cx,bx mov ds, ax mov bx,ax mov ax, 2 mov ax,1 mov bx, 3 l1: call hammu mul bx mov tong,ax loop l1 mov ax, 3 pop cx call hammu pop bx 54
  • 55.
    ret end begin hammu endp Trong chương trình này ta sӱ dөng thanh ghi ax là tham sӕ hình thӭc đӇ truyӅn cho chương trình con. Sau khi gӑi hammu lҫn 1, kӃt quҧ thӵc hiӋn cӫa chương trình con đưӧc lưu vào thanh ghi ax, vì đưӧc dùng làm tham sӕ nên ax sӁ bӏ thay đәi khi ta gӑi hammu lҫn 2, vì vұy đӇ bҧo vӋ kӃt quҧ ta lưu kӃt quҧ vào mӝt biӃn tәng. Ví dө 2: ViӃt chương trình con dùng đӇ kiӇm tra mӝt sӕ là chҹn hay là lҿ: .model small pop bx .code ret org 100h hammu endp begin: chanle proc jmp entry push ax c db "chan$" push bx l db "le$" push cx tong dw 0 mov bl,2 entry: div bl mov ax, @data cmp ah,0 mov ds, ax je chan mov ax, 2 lea dx,l call chanle mov ah,9 mov ax, 3 int 21h call chanle jmp kt int 20h chan: hammu proc lea dx,c push bx mov ah,9 push cx int 21h mov cx,bx kt: mov bx,ax pop cx mov ax,1 pop bx l1: pop ax mul bx ret loop l1 chanle endp pop cx end begin Trong mӝt chương trình có thӇ có nhiӅu hơn mӝt chương trình con. Như bҥn thҩy ӣ chương trình trên. 55
  • 56.
    Ví dө 3:Hãy viӃt chương trình con ASM cho phép nhұn mӝt sӕ nguyên (- 32768 ~ 32767) tӯ bàn phím kӃt thúc nhұn mӝt sӕ nguyên bҵng phím Enter (13 = 0dh). KӃt quҧ nҵm trong thanh ghi ax. Chú ý không cho phép đánh sai và sӱa. a) Nhұn sӕ nguyên dương - Dùng hàm nhұn kí tӵ mov ah, 1 int 21h Suy ra al chӳa mã ASCII cӫa kí tӵ. al ± 30h: thành mã ASCII chuyӇn thành sӕ - Sӕ vӯa đưa vào sӁ cӝng phҫn sӕ đã cҩt vào trưӟc *10 b) Nhұn mӝt sӕ nguyên âm - Có 1 biӃn cӡ dҩu: 0 là sӕ dương, 1 là sӕ âm. NӃu phát hiӋn kí tӵ đҫu là dҩu âm thì biӃn cӡ dҩu sӁ bҵng 1. Nhұn mӝt sӕ nguyên dương sau đó hӓi biӃn cӡ dҩu. NӃu cӡ dҩu = 1 thì chuyӇn sang sӕ bù 2 đӇ đәi dҩu. vsn proc sub al,30h push bx xchg ax,cx push cx mul bx push dx add cx,ax push si jmp l1 mov bx,10 l3: xor cx,cx cmp si,0 mov si,cx je l4 l1: neg cx mov ah,1 l4: int 21h mov ax,cx cmp al,13 pop si je l3 pop dx cmp al,'-' pop cx jne l2 pop bx inc si ret jmp l1 vsn endp l2: xor ah,ah Ví dө 4: ViӃt chương trình con hiӋn nӝi dung có trong AX ra ngoài màn hình dҥng cơ sӕ 10. 56
  • 57.
    Thuұt toán: a) AX chӭa sӕ nguyên dương Thuұt toán: vòng loop X: pop ax mov ah, 0ch int 10h loop X b) AX chӭa sӕ âm KiӇm tra hiӋn AX ” 0 NӃu AX ” 0 hiӋn dҩu ra màn hình sau đó đәi dҩu AX rӗi hiӋn như mӝt sӕ nguyên dương sau dҩu trӯ. Chương trình hsn proc neg ax push ax push ax push bx mov al,'-' push cx mov ah,0eh push dx int 10h mov bx,10 pop ax xor cx,cx l2: l1: xor dx,dx and ax,ax div bx jns l2 inc cx 57
  • 58.
    push dx loop l3 cmp ax,0 pop dx jne l2 pop cx l3: pop bx pop ax pop ax add ax,30h ret mov ah,0eh hsn endp int 10h end begin 4.2 Chương trình đa tӋp Trong các mөc trưӟc chúng ta chӍ biӃt cách viӃt ra mӝt chương trình cӥ nhӓ trên mӝt file (tӋp) .asm. Chương trình trên mӝt tӋp ngҳn, đơn giҧn và dӉ viӃt. Tuy nhiên đӕi vӟi chương trình cӥ vӯa và lӟn tӕt nhҩt là chúng ta chia thành nhiӅu tӋp (module) khi viӃt chương trình, sau đó dӏch và liên kӃt chúng lҥi vӟi nhau. Chương trình viӃt trên nhiӅu tӋp có thuұn lӧi như sau: y Cho phép nhiӅu ngưӡi dùng tham gia vào giҧi quyӃt vҩn đӅ y ViӋc kiӇm soát lӛi và sӱa lӛi trên tӯng module riêng biӋt nên có nhiӅu thuұn lӧi hơn. Vì mӛi module thưӡng giҧi quyӃt mӝt vҩn đӅ nhӓ riêng. 4.2.1 LӋnh điӅu khiӇn PUBLIC Chͱc năng: báo cho chương trình dӏch ASM biӃt module (tӋp) này cho phép các tӋp khác đưӧc dùng nhӳng nhãn nào mà không cҫn xác lұp lҥi. Cú pháp: PUBLIC Tên nhãn Xác lұp nhãn y Trưӡng hӧp nhãn là tên biӃn : .DATA PUBLIC Tên biӃn Khai báo biӃn Ví dө: .DATA PUBLIC x,y x db ? y dw ? y Trưӡng hӧp nhãn là tên chương trình con : .CODE PUBLIC Tên chương trình con 58
  • 59.
    Tên chương trìnhcon PROC RET Tên chương trình con ENDP 4.2.2 LӋnh điӅu khiӇn EXTERN Chͱc năng: báo cho chương trình dӏch ASM biӃt tӋp này xin phép dùng các nhãn mà các modul khác đã xác lұp và cho phép. Cú pháp: EXTRN Tên nhãn: KiӇu y Trưӡng hӧp vӟi nhãn là biӃn nhӟ : .DATA EXTRN Tên biӃn: KiӇu PUBLIC BYTE db WORD dw DWORD dd Ví dө: .DATA EXTRN X:BYTE, Y:WORD y Trưӡng hӧp nhãn là tên chương trình con: .CODE EXTRN Tên chương trình con:PROC 4.2.3 LӋnh điӅu khiӇn GLOBAL LӋnh điӅu khiӇn GLOBAL có thӇ thay thӃ cҧ hai lӋnh PUBLIC và EXTRN ӣ trên khi ta dùng chương tình dӏch TASM. NӃu chúng ta khai báo GLOBAL cho các nhãn có kèm theo khai báo dҥng nhãn thì GLOBAL khi đó thay thӃ cho PUBLIC, còn khi dùng GLOBAL khai báo nhãn đi sau có kèm theo kiӇu nhãn thì lúc đó GLOBAL thay thӃ co EXTRN. Ví dө GLOBAL thay thӃ cho PUBLIC: .DATA GLOBAL n,m,a N EQU 10 A DB n DUP(?) M DW 15 Ví dө GLOBAL thay thӃ cho EXTRN: .DATA GLOBAL X:BYTE, Y: WORD 59
  • 60.
    .CODE GLOBAL NEARPROC:NEAR Call nearpro Chú ý: Sau khi viӃt chương trình cho các module riêng biӋt bây giӡ ta phҧi dӏch và liên kӃt các module lҥi vӟi nhau. Quá trình liên kӃt như sau: y Dùng chương trình dӏch đӇ dӏch các module (file.ASM) thành các file .OBJ y Dùng chương trình liên kӃt LINK hay TLINK đӇ liên kӃt các .OBJ lҥi vӟi nhau theo cú pháp: TLINK module1.obj+module2.obj+«+modulen.obj Như vұy nó sӁ tҥo ra file thi hành đưӧc có tên là module1.exe. NӃu muӕn dӏch ra file .com thì ta thêm tham sӕ /t như bình thưӡng. Ví dө: viӃt chương trình tính n!, trong đó module chính khai báo mӝt biӃn n, gӑi chương trình con cho nhұp vào mӝt sӕ tӯ module thӭ 2, gӑi chương trình con tính giai thӯa tӯ module thӭ 3, và cuӕi cùng gӑi mӝt chương trình con hiӋn kӃt quҧ tӯ module thӭ 2. Module 2: module hiӋn và nhұp mӝt sӕ .model small cmp al,'-' .stack 100h jne vsn2 .data inc si .code jmp vsn1 begin: vsn2: public vsn,hsn xor ah,ah vsn proc sub al,30h push bx xchg ax,cx push cx mul bx push dx add cx,ax push si jmp vsn1 mov bx,10 vsn3: xor cx,cx cmp si,0 mov si,cx je vsn4 vsn1: neg cx mov ah,1 vsn4: int 21h mov ax,cx cmp al,13 pop si je vsn3 pop dx 60
  • 61.
    pop cx hsn2: pop bx xor dx,dx ret div bx vsn endp inc cx hsn proc push dx push ax cmp ax,0 push bx jne hsn2 push cx hsn3: push dx pop ax mov bx,10 add ax,30h xor cx,cx mov ah,0eh hsn1: int 10h and ax,ax loop hsn3 jns hsn2 pop dx neg ax pop cx push ax pop bx mov al,'-' pop ax mov ah,0eh ret int 10h hsn endp pop ax end begin Module 3: Có chương trình con tính giai thӯa cӫa mӝt sӕ, vӟi sӕ cҫn tính là biӃn public n cӫa module 1. Sau khi tính toán, module 3 lưu kӃt quҧ vào mӝt biӃn public là kq, sau này module 1 (module chính) sӁ dùng biӃn này đӇ lҩy vӅ kӃt quҧ. .model small public gth .stack 100h gth proc .data push ax extrn n:word push bx public kq push cx kq dw ? push dx .code mov cx,n begin: mov ax,1 mov ax,@data l1: mov ds,ax mul cx mov ah,4ch loop l1 int 21h mov kq,ax 61
  • 62.
    pop dx ret pop cx gth endp pop bx end begin pop ax Module 1: Khai báo biӃn public n (sӕ cҫn tính giai thӯa), gӑi chương trình con nhұp sӕ n vào tӯ bàn phím (chương trình con cӫa module 2), gӑi chương trình con tính giai thӯa cӫa n (chương trình con cӫa module 3), hiӋn kӃt quҧ thông qua biӃn public kq cӫa module 3(module 2). .model small ,hsn:near .stack 100h ,gth:near .data call vsn PUBLIC n mov n,ax n dw ? call gth EXTRN kq:word mov ax,kq .code call hsn begin: mov ah,4ch mov ax,@data int 21h mov ds,ax end begin extrn vsn:near 4.2.4. TӋp INCLUDE và cách dùng Như ӣ trên ta đã đӅ cұp đӃn chương tình lӟn có thӇ chia thành nhiӅu module và ta phҧi dӏch tҩt cҧ các module đó mӛi khi có thay đәi. Tuy nhiên có nhӳng lúc ta thay đәi các mudule mà không phҧi dӏch lҥi các module đó mà chӍ đӏnh mӝt module chính mà thôi. ĐӇ giҧi quyӃt vҩn đӅ đó chương trình dӏch ASM có mӝt lӋnh là INCLUDE. 4.2.4.1. Cú pháp và cơ chӃ tiӃn hành dӏch khi gӑi tӋp INCLUDE Cú pháp: INCLUDE tên tӋp Trong đó tên tӋp ta chӍ ra mӝt tӋp chӭa mӝt khӕi lӋnh ASM mà ta muӕn nӕi nó vào vӏ trí mà có lӋnh INCLUDE đӭng. LӋnh này có tác dөng copy toàn bӝ nӝi dung cӫa tӋp đưӧc chӍ ra sau đó đһt nó vào vӏ trí cӫa lӋnh INCLUDE. Ví dө: Mӝt tӋp có tên là ASM có tên là main.asm : « 62
  • 63.
    .CODE « Mov dx, offset tb1 Include hiens « Int 20h Trong đó tӋp hiens có nӝi dung như sau: Mov ah,09h Int 21h Thì khi dӏch tӋp main.asm nó sӁ có kӃt quҧ như sau: « .CODE Mov dx, offset tb1 Mov ah,09h Int 21h « Int 20h 4.2.4.2. Vҩn đӅ tìm tӋp INCLUDE Vҩn đӅ là chương trình dӏch cӫa ASM sӁ tìm lӋnh INCLUDE ӣ đâu: y NӃu trong tên tӋp có chӍ rõ đưӡng dүn thì chương trình dӏch sӁ tìm tӋp ӣ thư mөc đó y NӃu trong tên tӋp không chӍ ra đưӡng dүn mà chӍ có tên tӋp thì chương trình dӏch sӁ tìm tӋp trong thư mөc hiӋn hành y NӃu không tìm ra tӋp thì chương trình dӏch sӁ báo lӛi 4.2.4.2. Ví dө Mӝt chương trình hoàn chӍnh phҧi cho phép ngưӡi dùng nhұp dӳ liӋu và và hiӇn thӏ đưӧc kӃt quҧ thӵc thi cӫa chương trình. Ta đã có các chương trình con đӇ thӵc hiӋn hai công viӋc nhұp xuҩt đó, tuy nhiên, trưӟc kia khi chưa sӱ dөng chương trình đa tӋp, mӛi lҫn viӃt mӝt chương trình mӟi chúng ta lҥi phҧi viӃt lҥi các chương trình con nhұp/xuҩt này. Bây giӡ vӟi INCLUDE, chúng ta sӁ không phҧi viӃt lҥi các chương trình con này nӳa mà chӍ cҫn viӃt nó trên mӝt file và dùng lӋnh INCLUDE đӇ thêm nó vào chương trình thay vì phҧi viӃt lҥi. Ví dө dưӟi đây mô tҧ cách dùng INCLUDE đӇ nҥp các chương trình con nhұp/xuҩt đӇ giҧi quyӃt bài toán ³tính t͝ng hai s͙ đưͫc nh̵p vào tͳ bàn phím´. 63
  • 64.
    Ta viӃt tӋplib.asm, chӭa các chương trình con nhұp xuҩt: vsn proc vsn endp push bx hsn proc push cx push ax push dx push bx push si push cx mov bx,10 push dx xor cx,cx mov bx,10 mov si,cx xor cx,cx vsn1: hsn1: mov ah,1 and ax,ax int 21h jns hsn2 cmp al,13 neg ax je vsn3 push ax cmp al,'-' mov al,'-' jne vsn2 mov ah,0eh inc si int 10h jmp vsn1 pop ax vsn2: hsn2: xor ah,ah xor dx,dx sub al,30h div bx xchg ax,cx inc cx mul bx push dx add cx,ax cmp ax,0 jmp vsn1 jne hsn2 vsn3: hsn3: cmp si,0 pop ax je vsn4 add ax,30h neg cx mov ah,0eh vsn4: int 10h mov ax,cx loop hsn3 pop si pop dx pop dx pop cx pop cx pop bx pop bx pop ax ret ret 64
  • 65.
    hsn endp ViӃt chương trình tính tәng hai sӕ đưӧc nhұp vào tӯ bàn phím: .model small .stack 100h .code begin: call vsn mov bx,ax call vsn add ax,bx call hsn mov ah,4ch int 21h include lib.asm end begin Tӯ bây giӡ, đӇ nhұp xuҩt đưӧc sӕ, bҥn chӍ cҫn include lib.asm vào chương trình. 4.2.5 MACRO và vҩn đӅ liên quan 4.2.5.1. Chӭc năng Macro thӵc chҩt rҩt đơn giҧn, nӃu chúng ta gán mӝt tên thay cho mӝt khӕi lӋnh và sau đó khi chương trình ASM gһp tên này ӣ đâu trong chương trình thì khӕi lӋnh đó sӁ đưӧc dӏch và đһt khӕi mã lӋnh đó vào vӏ trí mà chương trình gӑi tên Macro. Có thӇ nói MACRO gҫn giӕng vӟi lӋnh INCLUDE, nó dùng mӝt tên thay cho mӝt khӕi mã lӋnh và khi chương trình dӏch ASM gһp tên này ӣ đâu thì nó dӏch và đһt khӕi lӋnh vào đó. Sӵ khác nhau giӳa MACRO và INCLUDE là: y MACRO có thӇ chuyӇn giao tham sӕ y MACRO có thӇ chӭa các nhãn cөc bӝ y MACRO tiӃn hành dӏch nhanh hơn. y MACRO có thӇ sӱ dөng các lӋnh điӅu khiӇn điӅu kiӋn khi dӏch 4.2.5.1. Khai báo (xác lұp) MACRO Cú pháp: 65
  • 66.
    Tên Macro Macro[đӕi] Bҧo vӋ các thanh ghi mà thân Macro phá vӥ Các lӋnh ASM trong thân Macro Hӗi phөc các thanh ghi mà thân Macro đã phá vӥ ENDM Ví dө: Hãy khai báo 1 Macro tҥo 1 lӋnh mӟi cho phép xoá toàn bӝ màn hình Cơ chӃ màn hình ӣ chӃ đӝ text, mӛi lҫn đһt mode cho màn hình thì màn hình sӁ bӏ xoá và con trӓ đӭng ӣ góc trên bên trái. Set mode: mov al, sӕ mode mov ah,0 int 10h Get mode: mov ah, 0fh int 10h MACRO sӁ đưӧc xây dӵng như sau: Clrscr MACRO push ax mov ah,0fh; get mode int 10h mov ah,0 int 10h; set mode pop ax ENDM Ví dө 2: Khai báo 1 Macro cho phép hiӋn 1 xâu lên màn hình Hienstring MACRO xau push ax dx lea dx, xau mov ah,9 int 21h pop dx ax ENDM 4.2.5.2. Cách dùng MACRO đã đưӧc xác lұp ViӋc sӱ dөng MACRO đã đưӧc khai báo chӍ đơn giҧn là gӑi tên MACRO. Ví dө muӕn gӑi MACRO xóa màn hình ta chӍ cҫn gӛ lӋnh: 66
  • 67.
    Clrscr MACRO và chương trình con khá giӕng nhau, tuy nhiên MACRO đưӧc khai bao ӣ đҫu chương trình chính, trong khi đó chương trình con thưӡng đưӧc khai báo ӣ cuӕi chương trình chính. MACRO thưӡng đưӧc sӱ dөng vì các nguyên nhân sau: y Thӵc hiӋn MACRO nhanh hơn là dùng chương trình con vì tránh đưӧc hai lӋnh là CALL và RET. y MACRO linh hoҥt hơn chương trình con vì nó có thӇ sӱ dөng các lӋnh điӅu khiӇn điӅu kiӋn dӏch và sӵ trao đәi thông sӕ hình thӭc, chúng ta có thӇ tҥo ra các mã lӋnh khác nhau nhҵm thӵc hiӋn các công viӋc gҫn giӕng nhau. Mà điӅu này thì chương trình con không làm đưӧc y MACRO có thӇ lӗng nhau Chú ý: Cơ chӃ cӫa chương trình dӏch khi gһp lӋnh mӟi Clrscr Hienstring M1 - ĐiӅu gì xҭy ra nӃu có lӋnh nhҧy trong Macro? Phҧi dùng Directive LOCAL Ví dө: X Macro LOCAL L1 L1: LOOP L1 ENDM 4.2.5.3. Ví dө Phҫn trên bҥn đã tҥo ra lib.asm đӇ sӱ dөng chương trình con nhұp xuҩt trong các chương trình ASM bҥn tҥo ra. Tuy nhiên, mӝt chương trình không thӇ là hoàn thiӋn nӃu thiӃu đi các chӍ thӏ cӫa chương trình, ví dө ³mӡi bҥn nhұp´, hay ³kӃt quҧ là´. ĐӇ thay vì viӋc phҧi viӃt lҥi macro hiens, chúng ta sӁ tҥo ra file lib2.asm chӭa macro này, và mӛi khi cҫn dùng, bҥn chӍ cҫn include lib2.asm. Dưӟi đây chúng ta sӁ cùng làm lҥi ví dө vӅ tính tәng hai sӕ: Tҥo ra lib2.asm có nӝi dung như sau: hiens macro s push ax push dx 67
  • 68.
    lea dx,s mov ah,9 int 21h pop dx pop ax endm ViӃt chương trình tính tәng 2 sӕ nhұp vào tӯ bàn phím sӱ dөng lib.asm và lib2.asm: .model small .stack 100h .data x1 db 10,"moi nhap: $" x2 db 10,"ket qua : $" .code include lib2.asm begin: mov ax,@data mov ds,ax ;hien xau moi nhap hiens x1 ;goi ctr nhap call vsn ;luu lai gtri nhap ;trong thanh ghi bx mov bx,ax ;hien xau moi nhap ;lan 2 hiens x1 ;goi ctr nhap call vsn ;ket qua nhap da ;nam trong ax ;ta tien hanh cong add ax,bx ;hien thi ket qua hiens x2 68
  • 69.
    call hsn movah,4ch int 21h include lib.asm end begin 69
  • 70.
    Chương 5: Cácthao tác vӟi tӋp 5.1 Thҿ File (File Handles) 5.1.1 Khӕi điӅu khiӇn file ± FCB (File Control Blocks) FCBs giӳ các thông tin vӅ file như tên ә đĩa chӭa file, tên file, kích thưӟc file,« Tuy nhiên, FCBs hҥn chӃ đӝ dài tӕi đa cӫa tên file là 11 kí tӵ, chính vì vұy mà khi dùng FCBs đӇ thao tác vӟi file ta chӍ có thӇ thao tác vӟi file ӣ thư mөc hiӋn thӡi. Tuy nhiên, các file hiӋn nay đưӧc chӍ ra bao gӗm cҧ tên thư mөc do vұy 11 kí tӵ là không thӇ đáp ӭng đưӧc và hãng IBM và Microsoft đã đưa ra khái niӋm thҿ file. Và tӯ phiên bҧn 2.0 cӫa DOS trӣ đi ngưӡi ta dùng thҿ file chӭ không dùng FCB nӳa. 5.1.2 Thҿ file Thҿ file là mӝt tӯ 16 bit làm đҥi diӋn cho mӝt file. Khi ta muӕn sӱ dөng mӝt file, ta trao cho DOS mӝt tên file có thӇ bao gӗm cҧ đưӡng dүn, còn DOS trҧ lҥi mӝt thҿ file trong mӝt thanh ghi, khi đó ta muӕn thao tác gì vӟi file, ví dө như đәi tên, mӣ file, đӑc file,... thì ta chӍ cҫn gӑi dӏch vө tương ӭng cӫa DOS sau khi đã cung cҩp cho nó mӝt tham sӕ và xuҩt trình thҿ file trong thanh ghi nào đó (BX). Chӭ không cҫn chӍ ra tên file nӳa. Mӝt điӅu cҫn biӃt đó là DOS coi các thiӃt bӏ ngoҥi vi như các file và nó gán cho mӛi file này mӝt thҿ file. Do đó ta có thӇ dùng các dӏch vө file cӫa DOS đӇ truy nhұp vào các thiӃt bӏ vұt lý khác nhau thông qua thҿ file cӫa chúng. Sau đây là mӝt sӕ thҿ file đã đưӧc DOS quy đӏnh sҹn : Thҿ file Tên thiӃt bӏ 0 ThiӃt bӏ vào chuҭn, thưӡng là bàn phím 1 ThiӃt bӏ ra chuҭn, thưӡng là màn hình 2 ThiӃt bӏ báo lӛi chuҭn 3 ThiӃt bӏ phө chuҭn 4 Máy in chuҭn 70
  • 71.
    5.2. Các dӏchvө dùng thҿ file cӫa DOS và các mã lӛi 5.2.1. Các dӏch vө dùng thҿ file cӫa DOS 5.2.1.1. Tҥo ra mӝt tӋp Hàm 3CH tҥo ra mӝt tӋp, mӣ nó đӇ truy nhұp đӑc ghi và chuyӇn giao mӝt tӯ truy nhұp tӋp. Trong quá trình này mӝt tӋp có cùng tên đang tӗn tҥi sӁ bӏ ghi đè. NӃu như muӕn tránh hұu quҧ này thì trưӟc hӃt ta phҧi thӱ mӣ tӋp này. NӃu sau đҩy xuҩt hiӋn thông báo lӛi là tӋp không đưӧc tìm thҩy và ta có thӇ yên tâm tҥo ra mӝt tӋp mӟi. Đҫu vào : y Nҥp vào thanh ghi AH giá trӏ 3CH : mov ah,3ch y DX trӓ tӟi xâu chӭa tên tӋp hoһc đưӡng dүn tӟi tӋp : lea dx, tên_tӋp Lưu ý tên tӋp là mӝt xâu kӃt thúc bӣi sӕ 0. y Nҥp vào CX thuӝc tính tӋp Đҫu ra: Khi dӏch vө đưӧc thӵc hiӋn tӕt: y CF=0 y AX chӭa tӯ truy nhұp tӋp hay thҿ tӋp Khi dӏch vө thӵc hiӋn có lӛi: y CF=1 y AX chӭa mã lӛi. AX=3 ~ đưӡng dүn không tìm thҩy, AX=4 ~ quá nhiӅu tӋp đưӧc mӣ, AX=5 ~ tӯ chӕi truy nhұp. Ví dө tҥo mӝt tӋp có tên là text1: .model small xor cx,cx; dat thuoc tinh cho .data ;tep pkey db "text1",0 int 21h .stack 100h ;thoat khoi chuong trinh .code kt: start: mov ah, 1 mov ax,@data int 21h mov ds,ax mov ax, 4c00h tao_tep_moi: int 21h lea dx,pkey; dx tro toi ten tep end start mov ah,3ch 71
  • 72.
    5.2.1.2. Mӣ mӝttӋp Dӏch vө 3DH mӣ mӝt tӋp đã đưӧc tҥo ra tӯ trưӟc và chuyӇn giao tӯ truy nhұp tӋp (thҿ tӋp). Tӯ này sӁ đưӧc dùng đӇ đӑc/ghi,« lên tӋp sau khi mӣ tӋp thành công. Đҫu vào: y Nҥp vào AH giá trӏ 3DH y DX trӓ tӟi xâu chӭa tên tӋp hoһc đưӡng dүn tӟi tӋp : lea dx, biӃn_tên_tӋp Lưu ý tên tӋp là mӝt xâu kӃt thúc bӣi sӕ 0. Đҫu ra: Khi dӏch vө đưӧc thӵc hiӋn tӕt: y CF=0 y AX chӭa tӯ truy nhұp tӋp hay thҿ tӋp Khi dӏch vө thӵc hiӋn có lӛi: y CF=1 y AX chӭa mã lӛi. AX=3 ~ không tìm thҩy tӋp. AX=4 ~ quá nhiӅu tӋp đưӧc mӣ, AX=5 ~ tӯ chӕi truy nhұp, AX=12 ~ truy nhұp không thuұn tiӅn, chӍ rõ là AL đã không đưӧc đһt bҵng giá trӏ hӧp lý. Ví dө mӣ mӝt tӋp: .model small mov al,0 .data mov ah,3dh pkey db "text1",0 int 21h write db 128 dup(?) jc kt read db 128 dup(?) mov bx,ax .stack 100h kt: .code mov ah, 1 start: int 21h mov ax,@data mov ax, 4c00h mov ds,ax int 21h mo_tep: end start lea dx,pkey 5.2.1.3. Khóa mӝt tӋp Dӏch vө 3EH khóa mӝt tӋp. Dӏch vө này thưӡng đưӧc sӱ dөng sau khi các thao tác vӟi tӋp đã đưӧc hoàn tҩt. 72
  • 73.
    Đҫu vào: y Nҥp vào AH giá trӏ 3EH y Nҥp nào BX thҿ tӋp (thưӡng đã có sҹn sau khi tҥo mӟi hay mӣ tӋp) Xuҩt ra: y Khi dӏch vө không thành công AX=6~ tӯ truy nhұp tӋp không đúng Ví dө đóng mӝt tӋp lҥi sau khi mӣ: .model small int 21h .data jc kt; nӃu mӣ tӋp có lӛi thì pkey db "text1",0 nhҧy đӃn nhãn kӃt thúc write db 128 dup(?) mov bx,ax; đưa vào bx thҿ read db 128 dup(?) tӋp .stack 100h ktt: ; đóng tӋp .code mov ah,3eh start: int 21h mov ax,@data kt: ; kӃt thúc chương trình mov ds,ax mov ah, 1 mo_tep: int 21h lea dx,pkey mov ax, 4c00h mov al,0 int 21h mov ah,3dh end start 5.2.1.4. Đӑc dӳ liӋu cӫa mӝt tӋp Dӏch vө 3FH chuyӇn các byte CX cӫa tӋp vào trong mӝt bӝ nhӟ đӋm đã đưӧc cho trưӟc bӣi chương trình ӭng dөng. Đҫu vào: y Nҥp vào AH giá trӏ 3FH y Nҥp nào BX thҿ tӋp (thưӡng đã có sҹn sau khi tҥo mӟi hay mӣ tӋp) y Nҥp vào CX sӕ các byte phҧi đӑc y DS:DX chӭa đӏa chӍ cӫa vùng đӋm dӳ liӋu (thưӡng là mӝt trưӡng sӕ, trưӡng sӕ này sӁ chӭa các dӳ liӋu đӑc ra tӯ file) Xuҩt ra: Khi dӏch vө đưӧc thӵc hiӋn tӕt: y CF=0 y AX chӭa sӕ byte phҧi đӑc, khi AX=0, sau đó hӃt tӋp (EOF)! Khi dӏch vө thӵc hiӋn có lӛi: y CF=1 73
  • 74.
    y AX chӭamã lӛi. AX=5 ~ tӯ chӕi truy nhұp, AX=6 ~ thҿ file không hӧp lӋ. Ví dө đӑc nӝi dung cӫa tӋp có tên là text1: .model small jc kt; đӑc tӋp lӛi .data cmp ax,0 pkey db "text1",0 je ktt ; hӃt tӋp write db 128 dup(?) mov cx,ax read db 128 dup(?) mov si,0 .stack 100h ht:; hiӇn thӏ thông tin .code mov dl,read[si] start: mov ah,2 mov ax,@data int 21h mov ds,ax inc si mo_tep: loop ht lea dx,pkey jmp re mov al,0 ktt:; xӱ lý hӃt tӋp mov ah,3dh mov ah,3eh int 21h int 21h jc kt;mӣ tӋp có lӛi kt: mov bx,ax; bx chӭa thҿ file mov ah, 1 re: ; đӑc tӋp int 21h mov dx,offset read; mov ax, 4c00h mov cx,128; sӕ byte cҫn đӑc int 21h mov ah,3fh; đӑc tӋp end start int 21h Trong ví dө trên ta, đӇ đӑc đưӧc tӋp, ta đӑc lҫn lưӧt 128 byte ra vùng đӋm (mӝt trưӡng sӕ có đӝ dài 128 byte): mov dx,offset read; dx chͱa đ͓a ch͑ cͯa trưͥng s͙ (vùng đ͏m) mov cx,128 ; s͙ byte c̯n đ͕c b̹ng đ͡ dài cͯa trưͥng s͙ mov ah,3fh; đ͕c ra vùng đ͏m int 21h jc kt ; nh̫y đ͇n k͇t thúc n͇u có l͟i trong khi đ͕c cmp ax,0 ; ki͋m tra xem đã k͇t thúc t͏p chưa je ktt ; n͇u là k͇t thúc t͏p thì nh̫y đ͇n nhãn x͵ lý k͇t thúc t͏p mov cx,ax; đưa s͙ kí t͹ (s͙ byte) vͳa đ͕c đưͫc vào thanh ghi l̿p mov si,0 74
  • 75.
    ht: mov dl,read[si]; đưa vào dl giá tr͓ n̹m trong tͳng byte cͯa trưͥng s͙ đ͋ ; hi͋n th͓ ra màn hình mov ah,2 int 21h inc si loop ht ; l̿p l̩i cho đ͇n khi cx=0 (hi͋n th͓ h͇t các byte cͯa đ͕c ;đưͫc tͳ file ± đang n̹m trong trưͥng s͙) Quá trình đӑc vào vùng đӋm 128 byte dӳ liӋu cӫa file phҧi đưӧc thӵc hiӋn lһp lҥi vì mӝt file có thӇ có nhiӅu hơn 128 byte dӳ liӋu. Ta dùng lӋnh nhҧy vô điӅu kiӋn đӇ lһp. re: ; đ͕c 128 byte dͷ li͏u cͯa file vào vùng đ͏m mov dx,offset read mov cx,128 mov ah,3fh int 21h jc kt cmp ax,0 je ktt mov cx,ax mov si,0 ht: mov dl,read[si] mov ah,2 int 21h inc si loop ht jmp re ; nh̫y l̩i nhãn cͯa đo̩n mã đ͕c 128 byte dͷ li͏u cͯa file vào vùng đ͏m khi đã đӑc hӃt tӋp, ta tiӃn hành đóng tӋp lҥi đӇ bҧo vӋ dӳ liӋu cӫa tӋp : ktt: mov ah,3eh int 21h 75
  • 76.
    5.2.1.5. Ghi vàomӝt tӋp Dӏch vө 40H chuyӇn giao các byte CX tӯ mӝt bӝ nhӟ đӋm đã cho trưӟc trong chương trình ӭng dөng vào mӝt tӋp: Đҫu vào: y Nҥp vào AH giá trӏ 40H y Nҥp nào BX thҿ tӋp (thưӡng đã có sҹn sau khi tҥo mӟi hay mӣ tӋp) y Nҥp vào CX sӕ các byte cҫn ghi y DX chӭa đӏa chӍ vùng đӋm Xuҩt ra: Khi dӏch vө đưӧc thӵc hiӋn tӕt: y CF=0 y AX chӭa sӕ lưӧng byte đưӧc ghi Khi dӏch vө thӵc hiӋn có lӛi: y CF=1 y AX chӭa mã lӛi. AX=5 ~ tӯ chӕi truy nhұp, AX=6 ~ thҿ tӋp không hӧp lӋ Ví dө vӅ ghi nӝi dung vào mӝt tӋp: .model small tiep: .data mov cx,128 pkey db "text1",0 mov si,0 write db 128 dup(?) nhap: read db 128 dup(?) mov ah,1 .stack 100h int 21h .code xor ah,ah start: cmp al,'?' mov ax,@data je kt_nap mov ds,ax mov write[si],al ;mӣ tӋp inc si lea dx,pkey loop nhap mov al,0 mov cx,128 mov ah,3dh mov dx,offset write int 21h mov ah,40h jc kt int 21h mov bx,ax jmp tiep ;ghi vào tӋp kt_nap: 76
  • 77.
    mov cx,si kt: mov dx,offset write mov ah, 1 mov ah,40h int 21h int 21h mov ax, 4c00h mov ah,3eh int 21h int 21h end start ĐӇ ghi đưӧc nӝi dung vào tӋp, đҫu tiên bҥn phҧi mӣ tӋp ra, rӗi đưa thҿ tӋp vào thanh ghi BX đӇ chuҭn bӏ ghi vào tӋp. ĐӇ ghi đưӧc vào tӋp, ta cҫn quy ưӟc sӁ ghi nào tӋp bao nhiêu byte, sau đó dùng mӝt vòng lһp có sӕ lҫn lһp trùng vӟi sӕ byte muӕn ghi đӇ cho ngưӡi dùng nhұp nӝi dung cҫn ghi nào: mov cx,128 ; s͙ ký t͹ (s͙ byte) mu͙n nh̵p vào mov si,0 nhap: ;cho ngưͥi dùng nh̵p dͷ li͏u vào mov ah,1 int 21h xor ah,ah cmp al,'?' ; so sánh ký t͹ nh̵p vào vͣi ký t͹ k͇t thúc vi͏c nh̵p je kt_nap ; n͇u ngưͥi dùng không mu͙n nh̵p nͷa thì nh̫y đ͇n nhãn ;kt_nap mov write[si],al ; chuy͋n ký t͹ ngưͥi dùng vͳa nh̵p vào vùng đ͏m inc si loop nhap ; l̿p l̩i vi͏c nh̵p Sau khi ngưӡi dùng đã nhұp hӃt sӕ ký tӵ cҫn nhұp, ta ghi sӕ ký tӵ đó vào vùng đӋm có tên là write bҵng dӏch vө 40h cӫa ngҳt 21h. mov cx,128 mov dx,offset write mov ah,40h int 21h Đoҥn mã trên chӍ cho phép nhұp 128 byte vào file, đӇ nhұp đưӧc nhiӅu hơn ta cҫn lһp lҥi đoҥn mã trên bҵng mӝt lӋnh nhҧy vô điӅu kiӋn ӣ cuӕi đoҥn mã: tiep: ; khͧi t̩o cho m͟i l̯n ghi 128 byte vào file mov cx,128 mov si,0 nhap: mov ah,1 77
  • 78.
    int 21h xor ah,ah cmp al,'?' je kt_nap mov write[si],al inc si loop nhap mov cx,128 mov dx,offset write mov ah,40h int 21h jmp tiep ; l̿p l̩i đo̩n mã nh̵p 128 byte vào file Khi ngưӡi dùng nhҩn nút ³?´ thì vòng lһp trên sӁ kӃt thúc, ta cҫn ghi nhӳng ký tӵ cuӕi cùng đưӧc nhұp vào file: kt_nap: mov cx,si mov dx,offset write mov ah,40h int 21h mov ah,3eh int 21h 5.2.1.6. Xóa mӝt tӋp Dӏch vө 41H cho phép xóa mӝt tӋp. Đҫu vào: y Nҥp vào AH giá trӏ 41H y DX trӓ tӟi xâu chӭa tên tӋp hoһc đưӡng dүn tӟi tӋp : lea dx, biӃn_tên_tӋp Lưu ý tên tӋp là mӝt xâu kӃt thúc bӣi sӕ 0. Xuҩt ra: Khi dӏch vө đưӧc thӵc hiӋn tӕt: y CF=0 Khi dӏch vө thӵc hiӋn có lӛi: y CF=1 y AH chӭa mã lӛi Ví dө: 78
  • 79.
    .model small .data pkey db "filetext",0 .stack 100h .code start: mov ax,@data mov ds,ax lea dx,pkey mov ah,41h int 21h mov ax, 4c00h int 21h end start 5.2.1.7. Di chuyӇn con trӓ đӇ truy cұp trӵc tiӃp vào vӏ trí mӟi Dӏch vө 42H cho phép di chuyӇn con trӓ file đi mӝt sӕ byte kӇ tӯ mӝt vӏ trí mӕc nào đó. Đҫu vào: y Nҥp vào AH giá trӏ 42H y Nҥp vào BX thҿ file y AL chӭa phương thӭc truy nhұp: 0: so vӟi đҫu tӋp 1: so vӟi vӏ trí hiӋn hành 2: so vӟi cuӕi tӋp y CX:DX chӭa sӕ lưӧng byte cҫn chuyӇn Xuҩt ra: y DX:AX chӭa vӏ trí mӟi cӫa con trӓ Ví dө: di chuyӇn con trӓ đӃn byte nhӟ thӭ 3 tính tӯ đҫu file: .model small .data pkey db "text1",0 dat db 128 dup(?) .stack 100h 79
  • 80.
    .code start: mov ax,@data mov ds,ax ;mӣ file ra đӇ đӑc lea dx,pkey mov al,0 mov ah,3dh int 21h ;sau khi mӣ file, ta có thҿ file, đưa thҿ file vào BX mov bx,ax ;di chuyӇn con trӓ đi 3 byte kӇ tӯ đҫu file mov al,0; điӇm mӕc là đҫu file mov ah,42h xor cx,cx mov dx,3; di chuyӇn con trӓ đi 3 byte int 21h ;lúc này con trӓ đang đӭng ӣ byte thӭ 4, ta thӱ đӑc 1 byte cӫa file ;đӇ kiӇm tra xem con trӓ đã dӏch chuyӇn chưa? lea dx,dat mov cx,1 mov ah,3fh int 21h ;hiӇn thӏ byte đưӧc đӑc mov dl,dat[0] mov ah,2 int 21h ;kӃt thúc mov ax, 4c00h int 21h end start ĐӇ kiӇm tra bҥn hãy nhұp vào file text1 nӝi dung là ³123456789´, sau khi đưӧc di chuyӇn 3 byte, con trӓ sӁ trӓ vào file thӭ 4 là sӕ ³4´. Khi chương trình trên đưӧc thӵc thi bҥn sӁ nhìn thҩy sӕ 4 trên màn hình. 80
  • 81.
    5.2.1.8. Đәi têntӋp Dӏch vө 56H cho phép xóa mӝt tӋp. Đҫu vào: y Nҥp vào AH giá trӏ 56H y DS:DX trӓ tӟi xâu chӭa tên cũ y ES:DI trӓ tӟi tên mӟi Xuҩt ra: Khi dӏch vө đưӧc thӵc hiӋn tӕt: y CF=0 Khi dӏch vө thӵc hiӋn có lӛi: y CF=1 y AH chӭa mã lӛi Ví dө: đәi tên tӋp tӯ text1 text .model small .data pkey db "text$",0 pkey1 db "text",0 dat db 128 dup(?) err db "co loi$" .stack 100h .code include lib2.asm start: mov ax,@data mov ds,ax ;chuyӇn xâu text sang ES:DI lea si,pkey1 l1: lodsb xor ah,ah cmp ax,0 je l2 stosb jmp l1 l2: 81
  • 82.
    ;DI trӓ vàođҫu xâu pkey1, DX trӓ vào đҫu xâu pkey movsb lea dx,pkey mov di,0 ;đәi tên mov ah,56h int 21h jnc kt hiens err kt: mov ax, 4c00h int 21h end start 5.2.2 Các mã lӛi trҧ vӅ Trong phiên bҧn DOS 4.0 có 91 lӛi khác nhau, các phiên bҧn vӅ sau thì sӕ mã lӛi còn lӟn hơn. Sau đây là mӝt sӕ mà lӛi thưӡng gһp: Mã lӛi Ý nghĩa 1 Sӕ hiӋu dӏch vө sai 2 Không tìm thҩy file 3 Không tìm thҩy đưӡng dүn 4 Mӣ quá nhiӅu file mӝt lúc 5 DOS tӯ chӛi không thӵc hiӋn thao tác này 6 Dùng thҿ file bӏ hӓng 7 Khӕi điӅu khiӇn MCB bӏ hӫy 8 Không có đӫ bӝ nhӟ 15 ChӍ đӏnh sai tên ә đĩa 16 Không thӇ xóa thư mөc hiӋn thӡi 19 Không thӇ ghi lên đĩa 21 ә đũa chưa sҹn sàng 23 Lӛi dӳ liӋu trên đĩa 25 Lӛi tìm rãnh trên đĩa 27 Không tìm thҩy sector 28 Máy in không có giҩy 29 Lӛi khi 82
  • 83.
    30 Lӛi đӑc 61 Hàng đӧi bӏ đҫy 83
  • 84.
    Chương 6 LiênkӃt giӳa ngôn ngӳ assembly vӟi các ngôn ngӳ bұc cao 6.1 Mӣ đҫu NhiӅu khi trong lұp trình, chúng ta muӕn viӃt mӝt chương trình mà trong đó có mӝt phҫn đưӧc viӃt bҵng ngôn ngӳ bұc thҩp như hӧp ngӳ và mӝt phҫn đưӧc viӃt bҵng ngôn ngӳ bұc cao đӇ có thӇ tұn dөng đưӧc sӭc mҥnh cӫa cҧ hai loҥi ngôn ngӳ này. Nhìn chung, viӋc liên kӃt hӧp ngӳ vӟi bҩt kǤ ngôn ngӳ bұc cao nào vӅ cơ bҧn là giӕng nhau. Do vұy trong giáo trình này chúng ta sӁ chӍ tìm hiӇu vӅ cách liên kӃt hӧp ngӳ vӟi C và Pascal. 6.2. Liên kӃt assembly vӟi ngôn ngӳ C Có hai cách đӇ liên kӃt giӳa C vӟi Assembler: y Cách 1: chèn các khӕi lӋnh hӧp ngӳ vào chương trình đưӧc viӃt bҵng ngôn ngӳ C ± inline assembly. Đây là phương pháp khá đơn giҧn và nhanh vì vӟi tӯ khóa asm đӭng trưӟc mӛi lӋnh, chúng ta có thӇ dӉ dàng đưa các lӋnh cӫa hӧp ngӳ vào giӳa các dòng lӋnh cӫa C. y Cách 2: viӃt tách biӃt nhiӅu module: o Bҵng ngôn ngӳ C o Bҵng hӧp ngӳ Sau đó tiӃn hành dӏch và liên kӃt chúng lҥi vӟi nhau. So vӟi cách 1, cách này sӁ phӭc ҥp hơn cho ngưӡi lұp trình song sӁ tránh đưӧc nhӳng nhưӧc điӇm mà cách 1 gһp phҧi. 6.2.1. Inline assembly trong C Cơ ch͇: Chèn khӕi lӋnh ASM vào chương trình đưӧc viӃt bҵng C/C++ Cú pháp: Các câu lӋnh C ASM lӋnh ASM ASM lӋnh ASM ASM lӋnh ASM Các câu lӋnh C hoһc cách khác: Các câu lӋnh C ASM { // dҩu ngoһc phҧi cùng mӝt dòng 84
  • 85.
    khӕi lӋnh ASM } Các câu lӋnh C Ví dͭ Tính Tәng 2 sӕ nguyên: #include "conio.h" #include "stdio.h" int a,b; void main(){ clrscr(); printf("moi nhap an"); scanf("%d",&a); printf("moi nhap bn"); scanf("%d",&b); asm mov ax,b asm add a,ax printf("tong la :%d",a); getch(); } Quá trình dӏch cӫa chương trình viӃt bҵng ngôn ngӳ C có xen các dòng lӋnh ASM sӁ tiӃn hành theo mӝt trình tӵ như sau: y Chương trình Turbo C sӁ dӏch tӋp nguӗn có đuôi .c sang tӋp .asm. y Chương trình dӏch TASM sӁ tiӃp tөc dӏch tӋp .asm sang tӋp có đuôi .obj. y TLINK sӁ thӵc hiӋn viӋc liên kӃt đӇ tҥo tӋp có đuôi .exe. Nhưͫc đi͋m cͯa vi͏c inline assembly C: y Các lӋnh nhҧy cӫa inline assembly chӍ có thӇ nhҧy đӃn các nhãn C (không thӇ nhҧy tӯ các nhãn inline assembly ra phҫn ngôn ngӳ C chӭ thӇ không cho phép chiӅu ngưӧc lҥi và cũng không thӇ thӵc hiӋn các lӋnh nhҧy trong lòng phҫn inline). y Nhãn nҵm trong phҫn cӫa C không thӇ là toán hҥng trong tҩt cҧ các lӋnh assembler cӫa inline assembly (trӯ các lӋnh nhҧy). 6.2.2. ViӃt tách biӋt nhiӅu module trong C Cách thưӡng dùng trong viӋc liên kӃt giӳa các chương trình viӃt bҵng ngôn ngӳ C vӟi các chương trình viӃt bҵng ngôn ngӳ assembly là viӃt hoàn toàn tách biӋt nhiӅu module riêng lҿ trong ngôn ngӳ C và ngôn ngӳ assembly. TiӃn hành 85
  • 86.
    dӏch các moduletheo tӯng module mӝt sau đó liên kӃt lҥi vӟi nhau đӇ tҥo ra các file thi hành đưӧc. Trưӟc khi tiӃn hành viӃt tách biӋt, chúng ta cҫn phҧi chú ý đӃn 3 vҩn đӅ sau: Vҩn đӅ 1: khi viӃt tách biӋt module C và module ASM thì vҩn đӅ cҫn giҧi quyӃt đҫu tiên là vҩn đӅ đa tӋp. ĐӇ 2 module có thӇ sӱ dөng các biӃn và các hàm cӫa nhau, ta cҫn phҧi khai báo public các hàm và biӃn cho phép đưӧc sӱ dөng chung, khi sӱ dөng các hàm và các biӃn này thì ta phҧi khai báo extern: y Không cҫn khai báo public vӟi các hàm, biӃn cӫa C, mһc đӏnh nó đã đưӧc coi là public y Cҫn khai báo public cho các hàm, biӃn dùng chung trong ASM y Khi sӱ dөng lҥi các hàm, biӃn cӫa C, ASM cҫn khai báo extrn: extrn tên_biӃn: kiӇu y Khi sӱ dөng lҥi các hàm, biӃn trong ASM, C cҫn khai báo extern: extern kiӇu tên_hàm(đӕi) Vҩn đӅ 2: trong module ASM, phҧi thêm dҩu µ_¶ trưӟc mӑi nhãn dùng chung vӟi C Lưu ý: đӕi vӟi C++, ta khai báo extern hàm trưӟc, rӗi sau đó dùng lӋnh sau đӇ dӏch tӯ file .cpp .asm: tcc ±S file.cpp Sau đó mӣ file .asm vӯa đưӧc dӏch ra, ta sӁ thҩy tên chương trình con ӣ cuӕi file, thông thưӡng, C sӁ thêm ký tӵ @ và $ vào tên hàm. Ví dө, hàm có tên là func1, thì C sau khi dӏch ra ASM sӁ đәi tên nó thành @func1$qv. Vҩn đӅ 3: Tên hàm cӫa ASM có giá trӏ trҧ vӅ nҵm trong AX hoһc DX:AX, vì vұy cҫn chú ý đưa kӃt quҧ vào AX khi viӃt hàm trong ASM. Sau khi chúng ta đã giҧi quyӃt đưӧc 3 vҫn đӅ trên và có hai tӋp viӃt bҵng C và bҵng assembly cӫa mӝt chương trình thì chúng ta tiӃn hành dӏch và liên kӃt bҵng lӋnh sau: Tcc ±ms/ls ±Ic:/tc/include ±Lc:/tc/lib tep1.cpp tep2.asm LӋnh dӏch trên báo cho chương trình dӏch Turbo C biӃt trưӟc tên phҧi dӏch file tep1.cpp thành file tep1.obj sau đó gӑi chương trình dӏch TASM dӏch file tep2.asm thành file tep2.obj và cuӕi cùng là gӑi TLINK đӇ liên kӃt tep1.obj và tep2.obj thành file thi hành đưӧc tep1.exe. ViӋc viӃt tách biӋt các module rҩt có lӧi cho các chương trình có sӕ lưӧng lӋnh assembly lӟn vì trong trưӡng hӧp này có thӇ sӱ dөng toàn bӝ khҧ năng cӫa chương trình dӏch assembly và dӏch phҫn assembly trong inline assembly. Không nhӳng thӃ phương pháp này cho ta khҳc phөc các nhưӧc điӇm cӫa inline assembly vҩp phҧi. 86
  • 87.
    Ví dө: viӃtmӝt chương trình đơn giҧn, cho nhұp vào mӝt biӃn, sau đó tăng giá trӏ cӫa biӃn đó lên 1 đơn vӏ và hiӋn giá trӏ vӯa đưӧc tăng đó lên màn hình. Ta sӁ trao nhiӋm vө nhұp và hiӇn thӏ biӃn cho C, và trao nhiӋm vө tăng giá trӏ cho ASM: Module C: #include "conio.h" #include "stdio.h" int a; extern int tang(); void main(){ clrscr; printf("nhap a");scanf("%d",&a); printf("%d",tang()); getch(); } Module ASM: .model small .data extrn _a:word .code begin: public @tang$qv @tang$qv proc mov ax,_a inc ax ret @tang$qv endp end begin 6.3 Liên kӃt assembly vӟi ngôn ngӳ pascal 6.3.1. Inline assembly trong Pascal Cũng giӕng như C,đӇ inline assembly trong Pascal chúng ta đһt các khӕi lӋnh assembler vào chương trình đưӧc viӃt bҵng ngôn ngӳ Pascal tҥi nơi nào chúng ta cҧm thҩy cҫn thiӃt. Dҥng tәng quát cӫa inline assembly trong chương trình viӃt bҵng Pascal như sau: 87
  • 88.
    asm các lӋnh asembler end; Mӛi khi chương trình dӏch Pascal gһp tӯ khóa asm trong dòng lӋnh inline assembly thì chương trình dӏch sӁ chuyӇn dòng lӋnh Assembly này vào dӏch vӟi viӋc quy chiӃu biӃn Pascal ra dҥng tương ӭng cӫa assembler đӇ thӵc hiӋn. Ví dө: viӃt chương trình tính tәng hai sӕ đưӧc nhұp vào tӯ bàn phím var a,b:integer; begin writeln('moi nhap a:');readln(a); writeln('moi nhap b:');readln(b); asm mov ax,b; add a,ax; end; writeln('tong la:',a); readln; end. Nhưӧc điӇm cӫa viӋc inline assembly trong Pascal: y Các lӋnh cӫa ASM đưӧc dӏch nhӡ qua chương trình dӏch cӫa Pascal y Các lӋnh nhҧy cӫa inline assembly chӍ có thӇ nhҧy đӃn các nhãn Pascal. 6.3.2. ViӃt tách biӋt nhiӅu module trong Pascal Tương tӵ như C, viӋc viӃt tách biӋt các nhiӅu module trong Pascal cũng có nghĩa là chúng ta viӃt chương trình đa tӋp, vӟi các tӋp Pascal và ASM riêng biӋt. Chúng ta cҫn giҧi quyӃt các vҩn đӅ sau khi tiӃn hành viӃt tách biӋt: Vҩn đӅ 1: phҧi khai báo public cho các biӃn, hàm dùng chung. Khi sӱ dөng phҧi khai báo extern: y Các biӃn, hàm trong Pascal không cҫn khai báo public y Các biӃn, hàm trong ASM phҧi khai báo public y Các biӃn, hàm muӕn đưӧc sӱ dөng lҥi, phҧi khai báo extrn trong ASM: extrn tên_biӃn: kiӇu y Các biӃn, hàm muӕn đưӧc sӱ dөng lҥi, phҧi khai báo external trong pascal: procedure (function)(đӕi sӕ):kiӇu;external; Vҩn đӅ 2: vҩn đӅ near/far cӫa chương trình con: 88
  • 89.
    Như chúng tađã biӃt, chương trình con near là chương trình con nҵm cùng segment vӟi chương trình chính, chương trình con far thì nҵm khác segment vӟi chương trình chính. Pascal quy ưӟc: y Các chương trình con đưӧc khai báo ӣ phҫn interface cӫa Unit luôn là far y Các chương trình con đưӧc khai báo trong chương trình đưӧc coi là near Song vì mӝt lý do nào đó thì chương trình con cũng có thӇ yêu cҫu far, đӇ làm đưӧc điӅu này, ta cҫn dùng lӋnh điӅu khiӇn {$F+} đӇ quy ưӟc vӟi Pascal rҵng các chương trình con đưӧc dӏch vӟi khai bào {$F+} sӁ là far. ĐӇ quay vӅ quy ưӟc ban đҫu, ta dùng lӋnh điӅu khiӇn {$F-} Vҩn đӅ 3: cҫn phҧi dùng lӋnh điӅu khiӇn {$L tên_file_asm.obj} đӇ báo cho chương trình dӏch cӫa pascal tìm đӃn tӋp ASM có thӇ ghép nӕi vӟi nó. Do đó sau khi viӃt chương trình asm song, ta tiӃn hành biên dӏch thành file obj, viӃt file pascal và biên dӏch chương trình pascal là đưӧc, không cҫn phҧi liên kӃt file bҵng tay như vӟi C. Ví du: tương tӵ ví dө trong phҫn viӃt tách biӋt vӟi ngôn ngӳ C, ta có các module Pascal và ASM như sau: var a:integer; {$F+} function tang:integer;external; {$L vd2[.obj]} {$F-} begin writeln('moi nhap '); readln(a); writeln(tang); readln end. Module ASM: .model large .data extrn a:word .code begin: public tang tang proc 89
  • 90.
    mov ax,a inc ax ret tang endp end begin 90