(** {0 Bibliothèque pour l'écriture de programmes X86-64 } Il s'agit là uniquement d'un fragment relativement petit de l'assembleur X86-64. @author Jean-Christophe Filliâtre (CNRS) @author Kim Nguyen (Université Paris Sud) *) (** {1 Code } *) type 'a asm (** type abstrait du code assembleur. Le paramètre ['a] est utilisé comme type fantôme. *) type text = [ `text ] asm (** du code assembleur se trouvant dans la zone de texte *) type data = [ `data ] asm (** du code assembleur se trouvant dans la zone de données *) type label = string (** les étiquettes d'addresses sont des chaînes de caractères *) val nop : [> ] asm (** l'instruction vide. Peut se trouver dans du text ou du data *) val ( ++ ) : ([< `text`data ] asm as 'a)-> 'a -> 'a (** concatène deux bouts de codes (soit text avec text, soit data avec data), en temps constant *) val inline: string -> [> ] asm (** [inline s] recopie la chaîne [s] telle quelle dans le fichier assembleur *) type program = { text : text; data : data; } (** un programme est constitué d'une zone de texte et d'une zone de données *) val print_program : Format.formatter -> program -> unit (** [print_program fmt p] imprime le code du programme [p] dans le formatter [fmt] *) val print_in_file: file:string -> program -> unit (** {1 Registres } *) type size = [`B `W `L `Q] type 'size register (** type abstrait des registres *) val rax: [`Q] register val rbx: [`Q] register val rcx: [`Q] register val rdx: [`Q] register val rsi: [`Q] register val rdi: [`Q] register val rbp: [`Q] register val rsp: [`Q] register val r8 : [`Q] register val r9 : [`Q] register val r10: [`Q] register val r11: [`Q] register val r12: [`Q] register val r13: [`Q] register val r14: [`Q] register val r15: [`Q] register (** registres 64 bits *) val eax: [`L] register val ebx: [`L] register val ecx: [`L] register val edx: [`L] register val esi: [`L] register val edi: [`L] register val ebp: [`L] register val esp: [`L] register val r8d: [`L] register val r9d: [`L] register val r10d: [`L] register val r11d: [`L] register val r12d: [`L] register val r13d: [`L] register val r14d: [`L] register val r15d: [`L] register (** registres 32 bits *) val ax: [`W] register val bx: [`W] register val cx: [`W] register val dx: [`W] register val si: [`W] register val di: [`W] register val bp: [`W] register val sp: [`W] register val r8w: [`W] register val r9w: [`W] register val r10w: [`W] register val r11w: [`W] register val r12w: [`W] register val r13w: [`W] register val r14w: [`W] register val r15w: [`W] register (** registres 16 bits *) val al: [`B] register val bl: [`B] register val cl: [`B] register val dl: [`B] register val ah: [`B] register val bh: [`B] register val ch: [`B] register val dh: [`B] register val sil: [`B] register val dil: [`B] register val bpl: [`B] register val spl: [`B] register val r8b: [`B] register val r9b: [`B] register val r10b: [`B] register val r11b: [`B] register val r12b: [`B] register val r13b: [`B] register val r14b: [`B] register val r15b: [`B] register (** registres 8 bits *) val register8: [`Q] register -> [`B] register (** accès au registre des 8 bits faibles d'un registre 64 bits *) (** {1 Opérandes } *) type 'size operand (** Le type abstrait des opérandes *) val imm: int -> [>] operand (** opérande immédiate $i *) val imm32: int32 -> [>] operand (** opérande immédiate $i *) val imm64: int64 -> [>] operand (** opérande immédiate $i *) val reg: 'size register -> 'size operand val (!%): 'size register -> 'size operand (** registre *) val ind: ?ofs:int -> ?index:'size1 register -> ?scale:int -> 'size2 register -> [>] operand (** opérande indirecte ofs(register, index, scale) *) val lab: label -> [>] operand (** étiquette L *) val ilab: label -> [`Q] operand (** étiquette immédiate $L *) (** {1 Instructions } *) (** {2 Transfert } *) val movb: [`B] operand -> [`B] operand -> text val movw: [`W] operand -> [`W] operand -> text val movl: [`L] operand -> [`L] operand -> text val movq: [`Q] operand -> [`Q] operand -> text (** attention : toutes les combinaisons d'opérandes ne sont pas permises *) val movsbw: [`B] operand -> [`W] register -> text val movsbl: [`B] operand -> [`L] register -> text val movsbq: [`B] operand -> [`Q] register -> text val movswl: [`W] operand -> [`L] register -> text val movswq: [`W] operand -> [`Q] register -> text val movslq: [`L] operand -> [`Q] register -> text (** avec extension de signe *) val movzbw: [`B] operand -> [`W] register -> text val movzbl: [`B] operand -> [`L] register -> text val movzbq: [`B] operand -> [`Q] register -> text val movzwl: [`W] operand -> [`L] register -> text val movzwq: [`W] operand -> [`Q] register -> text (** avec extension par zéro *) val movabsq: [`Q] operand -> [`Q] register -> text (** copie une valeur immédiate 64 bits dans un registre *) val cmove : 'size operand -> 'size operand -> text (* = 0 *) val cmovz : 'size operand -> 'size operand -> text (* = 0 *) val cmovne: 'size operand -> 'size operand -> text (* <> 0 *) val cmovnz: 'size operand -> 'size operand -> text (* <> 0 *) val cmovs : 'size operand -> 'size operand -> text (* < 0 *) val cmovns: 'size operand -> 'size operand -> text (* >= 0 *) val cmovg : 'size operand -> 'size operand -> text (* > signé *) val cmovge: 'size operand -> 'size operand -> text (* >= signé *) val cmovl : 'size operand -> 'size operand -> text (* < signé *) val cmovle: 'size operand -> 'size operand -> text (* <= signé *) val cmova : 'size operand -> 'size operand -> text (* > non signé *) val cmovae: 'size operand -> 'size operand -> text (* >= non signé *) val cmovb : 'size operand -> 'size operand -> text (* < non signé *) val cmovbe: 'size operand -> 'size operand -> text (* <= non signé *) (** copie conditionnelle (attention : toutes les combinaisons d'opérandes ne sont pas permises) *) (** {2 Arithmétique } *) val leab: [`B] operand -> [`B] register -> text val leaw: [`W] operand -> [`W] register -> text val leal: [`L] operand -> [`L] register -> text val leaq: [`Q] operand -> [`Q] register -> text val incb: [`B] operand -> text val incw: [`W] operand -> text val incl: [`L] operand -> text val incq: [`Q] operand -> text val decb: [`B] operand -> text val decw: [`W] operand -> text val decl: [`L] operand -> text val decq: [`Q] operand -> text val negb: [`B] operand -> text val negw: [`W] operand -> text val negl: [`L] operand -> text val negq: [`Q] operand -> text val addb: [`B] operand -> [`B] operand -> text val addw: [`W] operand -> [`W] operand -> text val addl: [`L] operand -> [`L] operand -> text val addq: [`Q] operand -> [`Q] operand -> text val subb: [`B] operand -> [`B] operand -> text val subw: [`W] operand -> [`W] operand -> text val subl: [`L] operand -> [`L] operand -> text val subq: [`Q] operand -> [`Q] operand -> text val imulw: [`W] operand -> [`W] operand -> text val imull: [`L] operand -> [`L] operand -> text val imulq: [`Q] operand -> [`Q] operand -> text val idivq: [`Q] operand -> text val cqto: text (** {2 Opérations logiques } *) val notb: [`B] operand -> text val notw: [`W] operand -> text val notl: [`L] operand -> text val notq: [`Q] operand -> text val andb: [`B] operand -> [`B] operand -> text val andw: [`W] operand -> [`W] operand -> text val andl: [`L] operand -> [`L] operand -> text val andq: [`Q] operand -> [`Q] operand -> text val orb : [`B] operand -> [`B] operand -> text val orw : [`W] operand -> [`W] operand -> text val orl : [`L] operand -> [`L] operand -> text val orq : [`Q] operand -> [`Q] operand -> text val xorb: [`B] operand -> [`B] operand -> text val xorw: [`W] operand -> [`W] operand -> text val xorl: [`L] operand -> [`L] operand -> text val xorq: [`Q] operand -> [`Q] operand -> text (** Opérations de manipulation de bits. "et" bit à bit, "ou" bit à bit, "not" bit à bit *) (** {2 Décalages } *) val shlb: [`B] operand -> [`B] operand -> text val shlw: [`W] operand -> [`W] operand -> text val shll: [`L] operand -> [`L] operand -> text val shlq: [`Q] operand -> [`Q] operand -> text (** note: shl est la même chose que sal *) val shrb: [`B] operand -> [`B] operand -> text val shrw: [`W] operand -> [`W] operand -> text val shrl: [`L] operand -> [`L] operand -> text val shrq: [`Q] operand -> [`Q] operand -> text val sarb: [`B] operand -> [`B] operand -> text val sarw: [`W] operand -> [`W] operand -> text val sarl: [`L] operand -> [`L] operand -> text val sarq: [`Q] operand -> [`Q] operand -> text (** {2 Sauts } *) val call: label -> text val call_star: [`Q] operand -> text val leave: text val ret: text (** appel de fonction et retour *) val jmp : label -> text (** saut inconditionnel *) val jmp_star: [`Q] operand -> text (** saut à une adresse calculée *) val je : label -> text (* = 0 *) val jz : label -> text (* = 0 *) val jne: label -> text (* <> 0 *) val jnz: label -> text (* <> 0 *) val js : label -> text (* < 0 *) val jns: label -> text (* >= 0 *) val jg : label -> text (* > signé *) val jge: label -> text (* >= signé *) val jl : label -> text (* < signé *) val jle: label -> text (* <= signé *) val ja : label -> text (* > non signé *) val jae: label -> text (* >= non signé *) val jb : label -> text (* < non signé *) val jbe: label -> text (* <= non signé *) (** sauts conditionnels *) (** {2 Conditions } *) val cmpb: [`B] operand -> [`B] operand -> text val cmpw: [`W] operand -> [`W] operand -> text val cmpl: [`L] operand -> [`L] operand -> text val cmpq: [`Q] operand -> [`Q] operand -> text val testb: [`B] operand -> [`B] operand -> text val testw: [`W] operand -> [`W] operand -> text val testl: [`L] operand -> [`L] operand -> text val testq: [`Q] operand -> [`Q] operand -> text val sete : [`B] operand -> text (* = 0 *) val setne: [`B] operand -> text (* <> 0 *) val setz : [`B] operand -> text (* = 0 *) val setnz: [`B] operand -> text (* <> 0 *) val sets : [`B] operand -> text (* < 0 *) val setns: [`B] operand -> text (* >= 0 *) val setg : [`B] operand -> text (* > signé *) val setge: [`B] operand -> text (* >= signé *) val setl : [`B] operand -> text (* < signé *) val setle: [`B] operand -> text (* <= signé *) val seta : [`B] operand -> text (* > non signé *) val setae: [`B] operand -> text (* >= non signé *) val setb : [`B] operand -> text (* < non signé *) val setbe: [`B] operand -> text (* <= non signé *) (** positionne l'octet opérande à 1 ou 0 selon que le test est vrai ou non *) (** {2 Manipulation de la pile} *) val pushq : [`Q] operand -> text (** [pushq r] place le contenu de [r] au sommet de la pile. Rappel : %rsp pointe sur l'adresse de la dernière case occupée *) val popq : [`Q] register -> text (** [popq r] place le mot en sommet de pile dans [r] et dépile *) (** {2 Divers } *) val label : label -> [> ] asm (** un label. Peut se retrouver dans du text ou du data *) val globl : label -> [> ] asm (** déclaration .globl (pour main, typiquement) *) val comment : string -> [> ] asm (** place un commentaire dans le code généré. Peut se retrouver dans du text ou du data *) val aligned_call_wrapper: f:string -> newf:string -> text (** construit une fonction assembleur `newf` qui appelle `f` après avoir correctement aligné la pile (sur un multiple de 16). Ainsi, `aligned_call "malloc" "malloc_"` ajoute au code assembleur une fonction `malloc_` qu'on peut appeler en tout endroit de notre code sans se soucier d'alignement. *) (** {2 Données } *) val string : string -> data (** une constante chaîne de caractères (terminée par 0) *) val dbyte : int list -> data val dword : int list -> data val dint : int list -> data val dquad : int list -> data (** place une liste de valeurs sur 1/2/4/8 octets dans la zone data *) val address: label list -> data (** place une liste d'adresses dans la zone data (avec .quad) *) val space: int -> data (** [space n] alloue [n] octets (valant 0) dans le segment de données *)
This document was generated using caml2html