Win3x.Org

Windows & DOS Community

Version bridée de macro-assembleur ?

Répondre   Page 2 sur 2  [ 11 messages ]
Aller sur la page « 1 2
Auteur Message
gm86
Sujet du message : Re: Version bridée de macro-assembleur ?
Publié : 03 mars 2020 13:56
Membre inscrit
Avatar de l’utilisateur
Hors-ligne
 
Messages : 630
Inscription : 01 sept. 2008 19:07
 
Nouvelle remontée.

En ce moment, je bidouille le format EXE. Le mot 12h d'un en-tête EXE (format MZ pour DOS) comporte le complément à un du checksum : cela signifie que l'addition sans retenue de tous les mots du fichier EXE (en-tête compris) donne FFFFh. Pour l'obtenir, LINK calcule d'abord le checksum avec le mot 12h nul :
http://bytepointer.com/download.php?nam ... xe_com.pdf
http://www.tavi.co.uk/phobos/exeformat.html
Je vais infirmer une de mes vieilles suppostions :
Citation :
- l'équipe Microsoft pour IBM ne savait pas quelle désignation donner à la directive !
Il est très simple de la faire avec le fichier ASM.EXE car son contenu tient dans un segment de mémoire. Il faut d'abord supprimer l'extension EXE pour forcer DEBUG à le charger comme un fichier binaire :
ren ASM.EXE *.
Il faut ensuite créer un le fichier texte ASM.TXT qui permettra de vérifier que l'ajout de la directive 286P, au bon endroit, renverra une somme de contrôle correcte (FFFFh) :
ad000
 xor dx,dx
 cld
 mov si,100
 lodsw
 add dx,ax
 dec cx
 loop d006

e999b '286P'
rip
d000
gd00c
q
- Fin -
Lors du chargement par DEBUG, la taille du fichier ASM est noté dans BX:CX (BX nul et CX < D000h - 100h dans le cas présent) :
debug asm < asm.txt
DEBUG obtient bien FFFFh dans DX !

Nous en déduisons que Microsoft a supprimé a posteriori la directive 286P, certainement pour mettre en avant sa version 3.00 par rapport à IBM :
http://bytepointer.com/masm/index.htm#MASM_3.0
D'ailleurs, heureusement que le DOS ne faisait pas usage de la somme de contrôle. Les fichiers ASM.EXE et MASM.EXE en version 2.00 (IBM) étaient théoriquement invalides. Il aurait été plus sage de remettre un mot nul à l'offset 12h de l'en-tête EXE :
http://www.fysnet.net/exehdr.htm


Samedi 7 mars

Avec le temps, même Microsoft préféra laisser un mot nul à l'offset 12h. Dans les cas contraire, le complément à un de la nouvelle somme de contrôle donnera zéro (NOT FFFFh) si le fichier EXE n'est pas altéré.

Voici un programme en QBasic pour MASM.EXE :
M$ = "Somme de contrôle correcte."
C$ = "Nouvelle somme de contrôle..."
E$ = "Mauvaise somme de contrôle !"
FICHIER$ = "MASM.EXE"
OPEN FICHIER$ FOR BINARY AS #1
IF LOF(1) = 0 THEN CLOSE : KILL FICHIER$: PRINT FICHIER$; " absent !": SYSTEM

FOR OCTET& = 1 TO LOF(1) STEP 2
        GET #1, OCTET&, MOT%
        IF OCTET& = &H13 THEN CONTROLE% = MOT%                  'Offset 12h
        LET SOMME& = (SOMME& + MOT%) AND &HFFFF&
NEXT

SOMME% = NOT VAL("&H" + HEX$(SOMME&))
IF SOMME% THEN IF CONTROLE% = 0 THEN PUT #1, &H13, SOMME%: M$ = C$ ELSE M$ = E$
PRINT M$
PRINT "NOT Checksum : "; HEX$(SOMME%); " ("; FICHIER$; ")"
SYSTEM
On découvre avec une erreur de calcul dans MASM 3 :
A>QBASIC /RUN CHECKSUM
Mauvaise somme de contrôle !
NOT Checksum : 100 (MASM.EXE)
Pour information, le mot suivant le nom complet des assembleurs IBM contient le mot 1. Il permet l'affichage du copyright IBM. Quant à MASM 3, il s'agit du mot précédant le nom. Mais il est à zéro vu qu'il ne s'agit pas d'une version OEM.


Lundi 9 mars

Bug de l'encodage de l'instruction 186 PUSH imm. remarqué par Charles Petzold :
http://books.google.fr/books?id=FC-L2faxEVkC&pg=PA326
http://books.google.fr/books?id=-9qzy8Z ... VQR&pg=292
Dans les versions 2.0 et 3.0 de MASM, l'instruction ADD AX,68h entre en jeu.

Après pistage de la valeur 1234h (test d'assemblage de PUSH 1234h) grâce à DEBUG et au désassemblage de MASM 2.0, je suis tombé sur le code incriminé en SEG+15h:3762h.


Samedi 14 mars

ASM.EXE, qui ne gère aucun code autre que 8086, incorpore pourtant la portion qui teste la suffisance d'un octet signé pour stocker un mot. Bien qu'elle soit utilisée, elle ne cause pas de bug à l'instruction CPM reg16≠AX,imm.

Par contre, il n'y a plus de test pour savoir si on a affaire à l'instruction PUSH imm., inexistante pour le 8086. On le voit en comparant le code en CS+124h:4FF5h avec celui de MASM 2.0 en CS+125h:5D34h. La valeur immédiate, d'une longueur d'un octet dans le pire des cas, est traduite en offset sans émettre de message d'erreur.


Le surlendemain

On remarque que l'instruction fictive POP imm. est malencontreusement traduite en PUSH imm. par MASM.


Jeudi 19 mars

À en croire Roger Schlafly, d'anciennement Borland International, l'option /ML apportée par MASM 3.0 altère la traduction d'une instruction 8087 écrite en minuscules.


Les lendemain et surlendemain

Je voulais m'attaquer au message manquant que pointait Roger Schlafly. C'est un problème commun à MASM 2.0, évidemment. Lorsque deux opérandes ST suivent une instruction 8087, MASM ignore le fait que l'un des deux ne soit pas le numéro zéro. Au lieu d'émettre un message d'erreur, il suppose que le deuxième est ST(0). MASM 5, lui, signale "error A2052: Improper operand type" comme lorsque l'opérande n'est pas un registre.

On peut traquer la gestion d'erreur, dans MASM 2.0, en en provoquant une. Il n'existe pas de registre ST dont le numéro va au-delà de 7. D'ailleurs, un éventuel signe moins provoquera aussi une "50:Value is out of range" à la deuxième passe.

En temps normal, le test remplace la valeur du premier opérande par le second. Il y en a forcément un de nul en absence de faute. Cela n'interfère pas avec les instructions 8087 n'ayant qu'un seul opérande : MASM met préalablement à zéro la destination.

Revenant au problème particulier de MASM 3.0, l'assembleur s'attend à ce que la deuxième lettre de l'instruction FLD soit une majuscule (comparaison en CS+125:50F3). D'où ce stupide bug qui demeure dans MASM/2.

Lundi 30 mars

Au retour de cette routine, on remarque que MASM a déjà traité l'instruction et qu'il n'a besoin de connaître que le numéro du registre autre que zéro. C'est pourquoi FMUL ST(n),ST(x) devient FMUL ST(n),ST. En intervenant ici, on laisserait le soin à l'erreur "63:Operand combination illegal", qui apparaît lorsque le dernier opérande des instructions 8087 à suffixe P n'est pas ST(0), d'être traitée ailleurs : FADDP ST(n),ST est par exemple valide.

Toutefois, on en reste là. Comme avec le bug commenté par Microsoft à propos de DUP (offset Variable) qui existe encore dans MASM 3.0 : DUP (Variable) évite que LINK signale une erreur voire, avec une version récente, remplace la valeur à répéter par zéro.


Dimanche 5 avril

Les fonctions de conversion numérique de la bibliothèque IBMUTIL.LIB sont expliquées dans l'ouvrage L'Assembler per l'80286/80386 :
$18_1NPUT	da stringhe ASCII a 80287/80387
$18_0UTPUT	da long real 80287/80387 a stringhe ASCII
$14_M4		da Microsoft singola a short real 80287/80387
$18_M8		da Microsoft doppia a long real 80287/80387
$M4_14		da short real 80287/80387 a Microsoft in singola precisione
$M8_18		da long real 80287/80387 a Microsoft in doppia precisione
$14_18		da long real 80287/80387 a short real 80287/80387
$18_14		da short real 80287/80387 a long real 80287/80387


1. Il segmento di codice deve essere dichiarato in questo modo:

CODMAT	SEGMENT	BYTE	PUBLIC	'CODE'
	EXTRN	$18_0UTPUT:NEAR

(Qui di seguito si inserisce il contenuto del segmento di codice)

CODMAT	ENDS

2. Il segmento dati viene dichiarato in questo modo:

DATI	SEGMENT	WORD	PUBLIC	'DATI'

(Qui di seguito si inserisce il contenuto del segmento di dati)

DATA	ENDS
DGROUP GROUP DATI

3. Tutte le routine sono procedure di tipo NEAR.

4. I registri DS e ES sono uguali.

5. Il contenuto di tutti i registri che non sono registri di segmento (ad eccezione
di SP) viene alterato.

6. SI:DS punta all'indirizzo (offset) del numero di tipo long real prima che
la routine venga chiamata.

7. Dopo l'esecuzione della routine, SI:DS punta all'indirizzo (offset) di
LSTRING. Questa è una locazione di memoria di 17 byte che contiene,
nel primo byte, la lunghezza della stringa ASCII prodotta. La virgola decimale
è a sinistra.

8. AX contiene il valore 1 se è stato utilizzato il numero originale, e il valore
0 se il numero da convertire era indefinito.

9. BL contiene un carattere spazio nel caso di numero positivo e una lineetta
nel caso di numero negativo.

10. DX contiene l'esponente del numero espresso nel formato in base 10.

Samedi 2 mai

L'indicateur du code en CS+125h:3762h est bon. Il renseigne les instructions SAR, SHL & SHR du 80186 que la valeur immédiate tient dans un entier 8 bits non signé. Le code en CS+125h:6785h de l'instruction CPM reg16≠AX,imm le remplace par l'inverse de l'indicateur précédent :
mov	ax,[si+0Dh]
xor	al,1
mov	[si+0Ch],al
C'est ce qui manque au code de l'instruction PUSH imm pour savoir si un entier 8 bits signé suffisait. De même, hélas, pour IMUL reg[,reg],imm.


Dimanche 17 mai

Le macro assembleur Microsoft.

SID de Digital Research accepte l'écriture de fichiers EXE, ainsi que l'arithmétique des segments de mémoire.

Microsoft MASM 1.27 avec correction du format LST en 80 colonnes (Page Symbols-1 sur une seule ligne) et du bug de l'an 2000 :
SID86
rMASM.EXE
sw12
0
.
sw1014
BB
.
sw1018
CA
.
sw101C
D9
.
sw1020
DF
.
sDS+1000:26B5
20
.
mDS+13C5:B1,+70,3D80
mDS+13C5:3D80,+70,B3
aCS+13C5:A9
mov    cx,#100
MOV    ax,[001E]
xor    dx,dx
div    cx

wMASM.EXE
q
NOT Checksum = F6A6h :
A>QBASIC /RUN CHECKSUM
Nouvelle somme de contrôle...
NOT Checksum : F6A6 (MASM.EXE)

A>QBASIC /RUN CHECKSUM
Somme de contrôle correcte.
NOT Checksum : 0 (MASM.EXE)
MASM 1.27 ne renvoie pas d'errorlevel (DOS 2 ou plus) s'il y a une erreur sévère.

L'assembleur IBM.

DEBUG returne la taille du fichier binaire dans les registres BX:CX, avec BX nul s'il tient dans un seul segment de mémoire.

IBM ASM 2.00 avec rétablissement de l'erreur PUSH imm (8086) et du bug de l'an 2000 :
REN ASM.EXE *.
DEBUG ASM
mCC62 CCC4 CC66
aCC5B
mov     cx,64
MOV     AX,[001C]
db      33 D2
div     cx
push    dx

e112 0 0
eC3A AD
eC3E BC
eC42 CB
eC46 D1
e999B '286P'
eB9C2 F4
a80
push cx
cld
mov si,100
lodsw
add dx,ax
dec cx
loop 85
not dx
mov [112],dx
pop cx

rip
80
g92
w
q
REN ASM *.EXE
NOT Checksum = C285h :
-rip
IP 0100
:80
-g92

AX=0000  BX=0000  CX=CBD6  DX=C285  SP=FFEE  BP=0000  SI=CCD6  DI=0000
ASM 2.00 renvoie un errorlevel 1 (DOS 2 ou plus) s'il y a une erreur sévère.

_________________

C:\ONGRTLNS.W95


Haut
Profil
Afficher : Trier par : Ordre :
Répondre   Page 2 sur 2  [ 11 messages ]
Revenir à « Documentations et tutoriels » | Aller sur la page « 1 2
Aller :