Sign in Join
Wiki copytemporary

Lazarus Inline Assembler/es: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11Esto es un esbozo para alentar a otros a contribuir con más información. A continuación un ejemplo sencillo como punto de partida [Lazarus_Inline_Assembler](http://wiki.freepascal.org/Lazarus_Inline_Assembler):
22
33``` pascal
44 unit unit_asm;
55 {$mode objfpc}{$H+}
66 interface
77 uses
88 Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls;
99 type
1010 { TForm1 }
1111 TForm1 = class(TForm)
1212 btnGo: TButton;
1313 edtInput: TEdit;
1414 edtOutput: TEdit;
1515 Label1: TLabel;
1616 Label2: TLabel;
1717 procedure btnGoClick(Sender: TObject);
1818 private
1919 { private declarations }
2020 public
2121 { public declarations }
2222 end;
2323 var
2424 Form1: TForm1;
2525 implementation
2626 { TForm1 }
2727
2828 procedure TForm1.btnGoClick(Sender: TObject);
2929 var
3030 num, answer : integer; {define dos variables de tipo entero: num (número) y answer (respuesta) }
3131 begin
3232 num := StrToInt(edtInput.Text); { Convierte la cadena a entero y se lo asigna a la variable num }
3333 // Se requiere esto con Lazarus en x86, definimos el modo ensamblador de Intel:
3434 {$ASMMODE intel}
3535 asm
3636 MOV EAX, num
3737 ADD EAX, 110B //sumar el numero 110 binario (6 en decimal) al contenido del registro EAX.
3838 SUB EAX, 2 //restar o substraer el número 2 decimal (no lleva la B de binario) al contenido del registro EAX.
3939 MOV answer, EAX //mover el contenido de EAX a la variable answer.
4040 end;
4141 edtOutput.Text := IntToStr(answer); { Convierte el número entero a su equivalente en cadena & pasa a la propiedad texto }
4242 end;
4343
4444 initialization
4545 {$I unit_asm.lrs}
4646 end.
4747```
4848
4949   En el siguiente enlace podéis encontrar una muy buena descripción al respecto en la documentación de FreePascal:
5050
5151- [Utilizando lenguaje ensamblador en el codigo fuente](http://www.freepascal.org/docs-html/prog/progse9.html), está en inglés así que lo pongo aquí traducido, añadiendo también este enlace [a directivas para ensamblador](http://www.freepascal.org/docs-html/prog/progsu3.html) y su respectiva traducción:
5252
53-` $ASMMODE : Modo ensamblador (Intel 80x86 solamente)`
53+```text
54+ $ASMMODE : Modo ensamblador (Intel 80x86 solamente)
55+```
5456
5557   La directiva {\$ASMMODE XXX} informa al compilador sobre el tipo de ensamblador que debe esperar en el/los bloques escritos en ensamblador. Aquí XXX debería reemplazarse por alguno de los siguientes valores:
5658
5759- **att:** Indica que los bloques asm contienen sintaxis en la modalidad ensamblador de AT&T.
5860
5961- **intel:** Indica que los bloques asm contienen sintaxis en la modalidad ensamblador de Intel.
6062
6163- **direct:** Indica al compilador que los bloques asm deben ser copiados directamente al fichero en ensamblador. No es posible utilizar estos bloques en ensamblador cuando se está utilizando un ensamblador interno por parte del compilador.
6264
6365   Estas opciones son locales y retienen su valor hasta el final de la unidad que es compilada, al menos que sean reemplazados utilizando alguna otra directiva del mismo tipo. La opción a nivel de línea de mandatos que corresponde a esto es -R.
6466
6567   En el IDE de Lazarus podemos encontrar estas opciones para el proyecto en curso:
6668
6769   El interprete de ensamblador predeterminado, si no se especifica otro, es AT&T.
6870
6971   Hay esencialmente 2 modos de embeber código ensamblador en código fuente pascal. La primera es la más simple y consiste en utilizar un bloque asm:
7072
7173``` pascal
7274 var
7375 I : Integer;
7476 begin
7577 I:=3;
7678 asm
7779 movl I,%eax
7880 end;
7981 end;
8082```
8183
8284   Todo lo que está contenido entre 'asm' y 'end' define un bloque que se inserta como código ensamblador en el código generado. Dependiendo del modo del interprete ensamblador, el compilador realizará la sustitución de ciertos nombres por sus direcciones.
8385
8486   El segundo modo es implementando una función o bien un procedimiento completamente en ensamblador. Esto se realiza añadiendo el modificador **assembler** a la cabecera de la función o procedimiento :
8587
8688``` pascal
8789 {$ASMMODE att} // pero recordar que es el que utiliza por defecto si no se especifica otro
8890 function geteipasebx : pointer;assembler;
8991 asm
9092 movl (%esp),%ebx
9193 ret
9294 end;
9395```
9496
9597   Es posible todavía declarar variables para el procedimiento en ensamblador:
9698
9799``` pascal
98100 procedure Move(const source;var dest;count:SizeInt);assembler;
99101 var
100102 saveesi,saveedi : longint;
101103 asm
102104 movl %edi,saveedi
103105 end;
104106```
105107
106108   El compilador reservará espacio en la pila para estas variables, esto inserta algunos comandos para ello.
107109
108110   Debemos tener en cuenta que el nombre ensamblador de una función en ensamblador todavía puede ser 'mangled' por el compilador. Por ejemplo la etiqueta para esta función no deberá ser el nombre de la función declarada. Para cambiar esto se puede utilizar un modificador Alias:
109111
110112``` pascal
111113
112114function geteipasebx : pointer;assembler;[alias:’FPC_GETEIPINEBX’];
113115 asm
114116 movl (%esp),%ebx
115117 ret
116118 end;
117119```
118120
119121   Para hacer que la función esté disponible en código ensamblador fuera de la unidad actual debemos añadir el modificador **public**:
120122
121123``` pascal
122124
123125function geteipasebx : pointer;assembler;[public,alias:’FPC_GETEIPINEBX’];
124126 asm
125127 movl (%esp),%ebx
126128 ret
127129 end;
128130```
129131
130132---
131133*From the Free Pascal wiki, page "Lazarus Inline Assembler/es", as it stood on 2020-02-18 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history