Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 16th, 2012  |  syntax: ASM (NASM)  |  size: 17.80 KB  |  hits: 20  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. ;NOM    = KERNEL.ASM : noyau de ESIos
  2. ;CLASSE = SYSTEME - DEVELOPPEMENT - ESIOS
  3. ;OBJET  = Programme illustrant la segmentation et la pagination sous x86
  4. ;HOWTO  = Exécuter le makefile pour compiler ce fichier
  5. ;AUTEUR = J.C. Jaumain
  6. ;PARTICIPATION : Mr Vanderseypen, 3G (2011-2012)
  7. ;BUGS   = On ne connait pas la longueur de l'instruction qui provoque l'int GP
  8. ;       = On ne teste pas RPL/DPL
  9. ;       = On ne teste pas l'utilisation d'un descripteur inéxistant
  10. ;       = int GP détruit EAX
  11. ;       = L'adresse des routine d'int doit être en 0x1xxxx
  12. ;==========================================================================
  13. %define DELAY   4000000000
  14. [BITS 32]
  15. ;==========================================================================
  16. ; KERNEL CHARGE : ce programme est en 0x10000
  17. ;==========================================================================
  18.         MOV ESI,txt_kernelLoad+0x10000
  19.         CALL affmessSuite
  20. ;==========================================================================
  21. ; Affiche la table des index des interruptions (TI) et un caractère (LI)
  22. ; correspondant, si cette interruption est gérée.
  23. ; G = global protection, P = page fault, H = horloge, C = clavier,
  24. ; E : Exception autre, I : IRQ autre, S : interruption autre,
  25. ; R : exécution du programme.
  26. ;==========================================================================
  27.         MOV ESI,TI+0x10000
  28.         MOV EDI,0xB8000
  29.         MOV BH,0xF
  30.         CALL affmessColor       ; TI en ligne 0
  31.         MOV ESI,LI+0x10000
  32.         MOV EDI,0xB8000+80*2    ; LI en ligne 1
  33.         MOV BH,0xF
  34.         CALL affmessColor
  35. ;===========================================================================
  36. ; Chargement de la table des interruptions
  37. ;===========================================================================
  38.         LIDT [idtptr+0x10000]
  39.         MOV ESI,txt_interruptTableLoad+0x10000 
  40.         CALL affmessSuite
  41. ;===========================================================================
  42. ; Initialisation du pic
  43. ;===========================================================================
  44.         CALL InitPic
  45.         MOV ESI,txt_picInit+0x10000    
  46.         CALL affmessSuite
  47. ;=========================================================================
  48. ; Creation de la directory (table des pages de niveau 1) en 0x20000
  49. ;=========================================================================
  50. Dir:    MOV EAX,0x21003         ; 0x21000 = addr TP | 3 (bits RW+P)
  51.         MOV EDI,0x20000         ; 0x20000 = addr directory
  52.         MOV [EDI],EAX  
  53. ;       -------------
  54.         MOV ECX,1023            ; 1023 autres
  55.         MOV EAX,0               ; entrées
  56. .autre: ADD EDI,4               ; sont
  57.         MOV [EDI],EAX           ; à zéro
  58.         LOOP .autre             ; et absentes
  59. ;==========================================================================
  60. ; creation de la première table des pages de niveau 2 en 0x21000
  61. ;==========================================================================
  62. TP:     MOV ECX,1024            ; | Toutes les entrées i de cette table
  63.         MOV EAX,3               ; | sont complététes avec le numéro de page i
  64.         MOV EDI,0x21000         ; | et sont présentes en mémoire
  65. .entree:MOV [EDI],EAX           ; | et sont accesibles en R/W (valeur 3  
  66.         ADD EAX,0x1000          ; | signifie que les 2 derniers bits sont à 1
  67.         ADD EDI,4               ; | => l'E.A. est en RAM aux même adesses
  68.         LOOP .entree            ; | Correction : Pour notre test, la page 14
  69.         MOV dword [0x21000+4*0x14],0    ; n'est pas en mémoire (entrée à 0)
  70.         MOV ESI,txt_pageTableCreate+0x10000    
  71.         CALL affmessSuite
  72. ;============================================================================
  73. ; activation de la pagination
  74. ;============================================================================
  75.         MOV EAX,0x20003         ; | adresse de la directory (20+003) dans le
  76.         MOV CR3,EAX             ; | registre CR3 (3 = 11b ==> R/W et Présent)
  77.         MOV EAX,CR0             ; | mise à 1 du bit 31
  78.         OR  EAX,0x80000000      ; | dans CR0 ( => bit 31 de CR0 mis à 1
  79.         MOV CR0,EAX             ; | signifie pagination active)
  80. ;============================================================================
  81. ; Rétablissement des interruptions
  82. ;============================================================================
  83.         STI
  84.         MOV ESI,txt_stiPageActiv+0x10000       
  85.         CALL affmessSuite
  86. ;============================================================================
  87. ; AFFICHAGE D'UN MESSAGE EN UTILISANT LE DESCRIPTEUR 3, ligne 21, position 1..4
  88. ; RAPPEL : base=0xB8000; limite=80*25*2=0xFA0 bytes; DPL 00; data; expand up; rw
  89. ;============================================================================
  90.         MOV ESI,txt_segmentBase+0x10000
  91.         CALL affmessSuite
  92.         MOV AX,11000b   ; index 3, GDT, RPL=00
  93.         MOV ES,AX
  94.         MOV byte [ES:80*21*2+1*2],'3'
  95.         MOV byte [ES:80*21*2+1*2+1],0x09
  96.         MOV byte [ES:80*21*2+2*2],':'
  97.         MOV byte [ES:80*21*2+2*2+1],0x09
  98.         MOV byte [ES:80*21*2+3*2],'O'
  99.         MOV byte [ES:80*21*2+3*2+1],0x09
  100.         MOV byte [ES:80*21*2+4*2],'K'
  101.         MOV byte [ES:80*21*2+4*2+1],0x09
  102.         CALL tempo
  103. ;============================================================================
  104. ; AFFICHAGE D'UN MESSAGE EN UTILISANT LE DESCRIPTEUR 4, ligne 21, position 6..9
  105. ; RAPPEL : base=0xB8000; limite=40*25*2=0x780 bytes; DPL 00; data; expand up; rw
  106. ;============================================================================
  107.         MOV ESI,txt_segmentOutOfLimit+0x10000  
  108.         CALL affmessSuite
  109.         MOV AX,100000b  ; index 4, GDT, RPL=00
  110.         MOV ES,AX
  111.         MOV byte [ES:80*21*2+6*2],'4'
  112.         MOV byte [ES:80*21*2+6*2+1],0x09
  113.         MOV byte [ES:80*21*2+7*2],':'
  114.         MOV byte [ES:80*21*2+7*2+1],0x09
  115.         MOV byte [ES:80*21*2+8*2],'K'
  116.         MOV byte [ES:80*21*2+8*2+1],0x09
  117.         MOV byte [ES:80*21*2+9*2],'O'
  118.         MOV byte [ES:80*21*2+9*2+1],0x09
  119.         CALL tempo
  120. ;============================================================================
  121. ; AFFICHAGE D'UN MESSAGE EN UTILISANT LE DESCRIPTEUR 5, ligne 21, posit.11..14
  122. ; RAPPEL : base=0xB8000; limite=80*25*2=0xFA0 bytes; DPL 00; data; expand up; r
  123. ;============================================================================
  124.         MOV ESI,txt_segmentReadOnly+0x10000    
  125.         CALL affmessSuite
  126.         MOV AX,101000b  ; index 5, GDT, RPL=00
  127.         MOV ES,AX
  128.         MOV byte [ES:80*21*2+11*2],'5'
  129.         MOV byte [ES:80*21*2+11*2+1],0x09
  130.         MOV byte [ES:80*21*2+12*2],':'
  131.         MOV byte [ES:80*21*2+12*2+1],0x09
  132.         MOV byte [ES:80*21*2+13*2],'K'
  133.         MOV byte [ES:80*21*2+13*2+1],0x09
  134.         MOV byte [ES:80*21*2+14*2],'O'
  135.         MOV byte [ES:80*21*2+14*2+1],0x09
  136.         CALL tempo
  137. ;============================================================================
  138. ; Appel d"une procédure en 0x14000 pour provoquer le défaut de page
  139. ;============================================================================
  140.         MOV ESI,txt_programLoad+0x10000         ; Message défaut de page
  141.         CALL affmessSuite
  142.         CALL tempo
  143.         CALL 0x8:0x14000        ; appel de la procédure en page 14
  144. ;=============================================================================
  145. ; Programme principal
  146. ; boucle infinie qui affiche un compteur temporisé en ligne 2, position 78
  147. ;=============================================================================
  148.         MOV ESI,txt_backMain+0x10000
  149.         CALL affmessSuite
  150. prog:   MOV EBX,54
  151.         CALL IncrInt
  152.         CALL tempo
  153.         MOV     AX,15   ; la mémoire renvoie le code de DIV CX dans RI
  154.         MOV CX,0        ; avec AX = 15, CX = 0
  155.         DIV CX          ; IP est incrémenté de la longueur de l'instruction
  156.                                 ; AX est divisé par CX, cela créer une exception de type
  157.                                 ; division par zéro ce qui provoque une interruption
  158.         JMP prog
  159. ;=============================================================================
  160. ;ROUTINE : InitPic
  161. ;OBJECTIF : Initialise les PIC pour les adapter à l'électronique du P.C.
  162. ;=============================================================================
  163. InitPic:MOV AL,0x11     ; 00010001 (icw4 utile)
  164.         OUT 0x20,AL     ; dans icw1
  165.         OUT 0xA0,AL     ; de l'esclave aussi
  166.         MOV AL,32       ; IRQ 0 en 32, ...
  167.         OUT 0x21,AL     ; dans icw2
  168.         MOV AL,40       ; IRQ 8 en 40...
  169.         OUT 0xA1,AL     ; de l'esclave aussi
  170.         MOV AL,0x4      ; patte 4
  171.         OUT 0x21,AL     ; dans icw3
  172.         MOV AL,0x2      ; patte 4
  173.         OUT 0xA1,AL     ; de l'esclave aussi
  174.         MOV AL,0x1      ; 00000001 (défaut)
  175.         OUT 0x21,AL     ; dans icw4    
  176.         OUT 0xA1,AL     ; de l'esclave aussi
  177.         MOV AL,0x0      ; aucun masque
  178.         OUT 0x21,AL    
  179.         OUT 0xA1,AL     ; pour l'esclave aussi
  180.         RET
  181. ;=============================================================================
  182. ;ROUTINE : tempo
  183. ;OBJECTIF : Effectue une temporisation
  184. ;=============================================================================
  185. tempo:  PUSH ECX
  186.         MOV ECX,DELAY
  187. .temp   LOOP .temp
  188.         POP ECX
  189.         RET
  190. ;=============================================================================
  191. ;ROUTINE : affmessColor
  192. ;OBJECTIF : Affiche un texte à 0 final
  193. ;ARGUMENTS :  
  194. ;       ESI : adresse du message, détruit
  195. ;       EDI : endroit ou commence le texte sur l'ecran, détruit
  196. ;       BH : couleur du texte
  197. ;=============================================================================
  198. affmessColor:
  199.         PUSH AX
  200. .aff:   MOV AL,[ESI]
  201.         CMP AL,0
  202.         JE  .fin
  203.         MOV [EDI],AL
  204.         INC EDI
  205.         MOV byte [EDI],BH
  206.         INC EDI
  207.         INC ESI
  208.         JMP .aff       
  209. .fin:   POP AX
  210.         RET
  211. ;=============================================================================
  212. ;ROUTINE : affmessSuite
  213. ;OBJECTIF : Affiche un texte à 0 final en blanc, à la ligne suivante
  214. ;ARGUMENTS :    ESI : adresse du message, détruit
  215. ;VARIABLES : currentLine (initialisé à 5.)
  216. ;=============================================================================
  217. affmessSuite:
  218.         PUSH AX
  219.         PUSH EDI
  220.         PUSH EBX
  221.         MOV EDI,[currentLine+0x10000]
  222.         MOV BH,0xF
  223.         CALL affmessColor
  224.         MOV EDI,[currentLine+0x10000]
  225.         ADD EDI,80*2
  226.         MOV [currentLine+0x10000],EDI
  227.         POP EBX
  228.         POP EDI
  229.         POP AX
  230.         RET
  231. ;=============================================================================
  232. ;ROUTINE : IncrInt
  233. ;OBJECTIF : Affiche et incrémente le compteur
  234. ;ARGUMENTS : EBX : numéro du compteur (0..54)
  235. ;VARIABLES : Cpt
  236. ;=============================================================================
  237. IncrInt:PUSH ESI
  238.         PUSH EAX
  239.         MOV ESI,Cpt
  240.         ADD ESI,EBX
  241.         MOV AL, [ESI+0x10000]   ; Le compteur numéro EBX dans AL
  242.         INC AL
  243.         CMP AL, '9'
  244.         JBE .continue
  245.         MOV AL,'0'
  246. .continue:
  247.         MOV byte [ESI+0x10000], AL      ; Modification du compteur en mémoire
  248.         MOV ESI,0xB8000+80*2*2  ; | Affichage du compteur en ligne 2,
  249.         ADD ESI,EBX             ; | position EBX
  250.         ADD ESI,EBX             ; | *2 car code couleur à l'affichage
  251.         MOV byte [ESI],AL       ; | en couleur verte.
  252.         MOV byte [ESI+1],0x0A   ; |
  253.         POP EAX                
  254.         POP ESI
  255.         RET
  256. ;=============================================================================
  257. ;                                    ROUTINES D'INTERRUPTION
  258. ;=============================================================================
  259. defEX:  PUSH EBX
  260.         MOV EBX,52      ; routine par défaut pour les exceptions
  261.         CALL IncrInt
  262.         POP EBX
  263.         IRET
  264. defIRQ: PUSH EBX
  265.         MOV EBX,53      ; routine par défaut pour les IRQ
  266.         CALL IncrInt
  267.         MOV AL,0x20    
  268.         OUT 0X20,AL     ; fin d'IRQ pour le PIC
  269.         POP EBX
  270.         IRET
  271. defSYS: PUSH EBX
  272.         MOV EBX,54      ; routine par défaut pour les appels système
  273.         CALL IncrInt
  274.         POP EBX
  275.         IRET
  276. gp:     PUSH EBX       
  277.         MOV EBX,13      ; routine pour 'global protection': détruit EAX
  278.         CALL IncrInt
  279.         POP EBX
  280.         ADD ESP,4       ; Elimination du code d'erreur déposé sur la pile
  281.         POP EAX         ; | Modification de l'adresse de retour pour que IRET
  282.         ADD EAX, 8      ; | retourne vers l'instruction qui suit celle qui a
  283.         PUSH EAX        ; | provoqué l'interruption (assume 8 bytes (BUG))
  284.         IRET
  285. pf:     PUSH EBX
  286.         PUSH ESI
  287.         PUSH EAX
  288.         MOV EBX,14      ; routine pour page fault
  289.         CALL IncrInt
  290.         MOV ESI,txt_pageFault+0x10000 ; Message
  291.         CALL affmessSuite
  292.         MOV dword [0x21000+4*0x14],0x11003  ; La page 14 présente, en page 11 
  293.         MOV EAX,0x20000 ; | Raffraichissement de la mémoire associative (cache)
  294.         MOV CR3,EAX     ; | en réécrivant l'adresse de la directory.
  295.         MOV ESI,txt_pageCorrect+0x10000 ; Message
  296.         CALL affmessSuite
  297.         POP EAX
  298.         POP ESI
  299.         POP EBX
  300.         ADD ESP,4       ; Elimination du code d'erreur déposé sur la pile
  301.         IRET
  302. divzero:
  303.         PUSH EBX
  304.         PUSH ESI
  305.         MOV EBX,0       ; routine pour 'division par zéro'
  306.         CALL IncrInt
  307.         MOV ESI,txt_divzero+0x10000 ; Message de division par zéro
  308.         CALL affmessSuite
  309.         POP ESI
  310.         POP EBX
  311.         ADD ESP,4       ; Elimination du code d'erreur déposé sur la pile
  312.         POP EAX         ; | Modification de l'adresse de retour pour que IRET
  313.         ADD EAX, 8      ; | retourne vers l'instruction qui suit celle qui a
  314.         PUSH EAX        ; | provoqué l'interruption (assume 8 bytes (BUG))
  315.         IRET
  316. horlog: PUSH EBX
  317.         MOV EBX,32      ; routine pour l'IRQ horloge
  318.         CALL IncrInt
  319.         POP EBX
  320.         MOV AL,0x20    
  321.         OUT 0X20,AL     ; fin d'IRQ pour le PIC
  322.         IRET
  323. clavier:PUSH EBX        ; routine pour l'IRQ clavier
  324. .checkp:IN AL,0x64      ; lecture du statut
  325.         XOR AL,0x01     ; pret?
  326.         JZ .checkp      ; on boucle tant que pas pret
  327.         IN AL,0x60      ; lecture du scan code
  328.         MOV EBX,33
  329.         CALL IncrInt
  330.         POP EBX
  331.         MOV AL,0x20    
  332.         OUT 0X20,AL     ; fin d'IRQ pour le PIC
  333.         IRET
  334. ;=============================================================================
  335. ;                                        TABLE D'INTERRUPTION
  336. ;=============================================================================
  337. ; table idt : 4 champs
  338. ;       addresse routine : 16 derniers bits, (offset dans ce programme)
  339. ;       segment CS de cette routine,
  340. ;       code 'routine d'interruption'
  341. ;       addresse routine : 16 premiers bits, (1 car programme en 0x10000)
  342. ; 0..31 : exceptions, 32..47 : IRQ, 48..255 : Utilisateur (INT)
  343. idt:    dw      divzero,0x0008,0x8E00,0x1       ;0 division par zéro
  344.         dw      defEX,0x0008,0x8E00,0x1 ;1 debug exception
  345.         dw      defEX,0x0008,0x8E00,0x1 ;2 NMI
  346.         dw      defEX,0x0008,0x8E00,0x1 ;3 Break point
  347.         dw      defEX,0x0008,0x8E00,0x1 ;4 INTO
  348.         dw      defEX,0x0008,0x8E00,0x1 ;5 Bound
  349.         dw      defEX,0x0008,0x8E00,0x1 ;6 invalid opcode
  350.         dw      defEX,0x0008,0x8E00,0x1 ;7 Device not available
  351.         dw      defEX,0x0008,0x8E00,0x1 ;8 Double fault
  352.         dw      defEX,0x0008,0x8E00,0x1 ;9 Copro segment overrun
  353.         dw      defEX,0x0008,0x8E00,0x1 ;10 Invalid task state segment
  354.         dw      defEX,0x0008,0x8E00,0x1 ;11 segment not present
  355.         dw      defEX,0x0008,0x8E00,0x1 ;12 stack segment fault
  356.         dw      gp,0x0008,0x8E00,0x1    ;13 general protection
  357.         dw      pf,0x0008,0x8E00,0x1    ;14 page fault
  358.         dw      defEX,0x0008,0x8E00,0x1 ;15 Reserved Intel
  359.         dw      defEX,0x0008,0x8E00,0x1 ;16 Floating point error
  360.         dw      defEX,0x0008,0x8E00,0x1 ;17 Alignement check
  361.         dw      defEX,0x0008,0x8E00,0x1 ;18 machine check
  362.         dw      defEX,0x0008,0x8E00,0x1 ;19 Reserved Intel
  363.         dw      defEX,0x0008,0x8E00,0x1 ;20 Reserved Intel
  364.         dw      defEX,0x0008,0x8E00,0x1 ;21 Reserved Intel
  365.         dw      defEX,0x0008,0x8E00,0x1 ;22 Reserved Intel
  366.         dw      defEX,0x0008,0x8E00,0x1 ;23 Reserved Intel
  367.         dw      defEX,0x0008,0x8E00,0x1 ;24 Reserved Intel
  368.         dw      defEX,0x0008,0x8E00,0x1 ;25 Reserved Intel
  369.         dw      defEX,0x0008,0x8E00,0x1 ;26 Reserved Intel
  370.         dw      defEX,0x0008,0x8E00,0x1 ;27 Reserved Intel
  371.         dw      defEX,0x0008,0x8E00,0x1 ;28 Reserved Intel
  372.         dw      defEX,0x0008,0x8E00,0x1 ;29 Reserved Intel
  373.         dw      defEX,0x0008,0x8E00,0x1 ;30 Reserved Intel
  374.         dw      defEX,0x0008,0x8E00,0x1 ;31  Reserved Intel
  375.         dw      horlog,0x0008,0x8E00,0x1        ;32 Timer
  376.         dw      clavier,0x0008,0x8E00,0x1       ;33 Clavier
  377.         dw      defIRQ,0x0008,0x8E00,0x1        ;34 Controleur esclave
  378.         dw      defIRQ,0x0008,0x8E00,0x1        ;35 série 2
  379.         dw      defIRQ,0x0008,0x8E00,0x1        ;36 série 1
  380.         dw      defIRQ,0x0008,0x8E00,0x1        ;37 // 2
  381.         dw      defIRQ,0x0008,0x8E00,0x1        ;38 diskette
  382.         dw      defIRQ,0x0008,0x8E00,0x1        ;39 // 1
  383.         dw      defIRQ,0x0008,0x8E00,0x1        ;40 Reserved IRQ
  384.         dw      defIRQ,0x0008,0x8E00,0x1        ;41 Reserved IRQ
  385.         dw      defIRQ,0x0008,0x8E00,0x1        ;42 Reserved IRQ
  386.         dw      defIRQ,0x0008,0x8E00,0x1        ;43 Reserved IRQ
  387.         dw      defIRQ,0x0008,0x8E00,0x1        ;44 Reserved IRQ
  388.         dw      defIRQ,0x0008,0x8E00,0x1        ;45 Copro
  389.         dw      defIRQ,0x0008,0x8E00,0x1        ;46 disk
  390.         dw      defIRQ,0x0008,0x8E00,0x1        ;47 Reserved IRQ------
  391.         dw      defSYS,0x0008,0x8E00,0x1 ;48
  392.         dw      defSYS,0x0008,0x8E00,0x1 ;49
  393.         dw      defSYS,0x0008,0x8E00,0x1 ;50
  394. idtend:
  395. ;=============================================================================
  396. ;       A PLACER DANS LE REGISTRE IDTR QUI POINTE VERS LA TABLE D'INTERRUPTION
  397. ;=============================================================================
  398. idtptr:
  399.         dw      idtend - idt            ; limite
  400.         dd      idt + 0x10000           ; base
  401. ;=============================================================================
  402. ; VARIABLES SYSTEME
  403. ;=============================================================================
  404. ;Textes
  405. ;------
  406. txt_kernelLoad          DB      'Chargement du kernel',0
  407. txt_interruptTableLoad  DB      'Chargement de la table des interruptions',0
  408. txt_picInit             DB      'Initialisation du pic',0
  409. txt_pageTableCreate     DB      'Creation des tables de pages',0
  410. txt_stiPageActiv        DB      'Activation interruptions et pagination',0
  411. txt_segmentBase         DB      'Utilisation du descripteur 3 pour affichage',0
  412. txt_segmentOutOfLimit   DB      'Protection globale : depassement de limite',0
  413. txt_segmentReadOnly     DB      'Protection globale : ecriture interdite',0
  414. txt_programLoad         DB      'Execution du programme a la page 0x14',0
  415. txt_pageFault           DB      'Warning : PAGE FAULT',0
  416. txt_pageCorrect         DB      'Maj de la table des pages : 0x14 en 0x11',0
  417. txt_backMain            DB      'Retour au programme principal',0
  418. txt_divzero             DB      'Division par zero',0
  419.  
  420. ;Variables utilitaires
  421. ;---------------------
  422. TI              DB '012345678901234567890123456789012345678901234567890----',0
  423. LI              DB '-------------GP-----------------HC-----------------EISR',0
  424. currentLine     DD 0xB8000+5*80*2       ; première ligne de message
  425. Cpt             times 55 db '0'         ; Les 55 compteurs d'interruption
  426. ;=============================================================================
  427. ; Remplissage par des NOP afin que la suite se trouve à l'adresse 0x11000
  428. ; quand tout ce code sera chargé en mémoire à l'adresse 0x10000.
  429. ; (0x11000 est 0x1000 plus loin que 0x10000)
  430. ;=============================================================================
  431. times 0x1000-($-$$) db 144
  432. ;=============================================================================
  433. ; La procédure qui se trouve en 0x11000 et qui sera appelée par CALL 0x8:0x14000
  434. ; Comme la table des pages contient 11 à l'index 14, cette routine sera exécutée
  435. ; Cette routine affiche HELLO à la ligne 22, colonne 50.
  436. ;=============================================================================
  437.         MOV byte [0xB8000+80*22*2+50*2],'H'
  438.         MOV byte [0xB8000+80*22*2+50*2+1],0x09
  439.         MOV byte [0xB8000+80*22*2+50*2+2],'E'
  440.         MOV byte [0xB8000+80*22*2+50*2+3],0x0A
  441.         MOV byte [0xB8000+80*22*2+50*2+4],'L'
  442.         MOV byte [0xB8000+80*22*2+50*2+5],0x03
  443.         MOV byte [0xB8000+80*22*2+50*2+6],'L'
  444.         MOV byte [0xB8000+80*22*2+50*2+7],0x03
  445.         MOV byte [0xB8000+80*22*2+50*2+8],'O'
  446.         MOV byte [0xB8000+80*22*2+50*2+9],0x0B
  447.         RET