Sign in Join
Wiki copytemporary

Lazarus Inline Assembler/es: what changed

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

Title: Lazarus Inline Assembler/es

OldNewLine
1+Esto 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):
2+
3+``` pascal
4+ unit unit_asm;
5+ {$mode objfpc}{$H+}
6+ interface
7+ uses
8+ Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls;
9+ type
10+ { TForm1 }
11+ TForm1 = class(TForm)
12+ btnGo: TButton;
13+ edtInput: TEdit;
14+ edtOutput: TEdit;
15+ Label1: TLabel;
16+ Label2: TLabel;
17+ procedure btnGoClick(Sender: TObject);
18+ private
19+ { private declarations }
20+ public
21+ { public declarations }
22+ end;
23+ var
24+ Form1: TForm1;
25+ implementation
26+ { TForm1 }
27+
28+ procedure TForm1.btnGoClick(Sender: TObject);
29+ var
30+ num, answer : integer; {define dos variables de tipo entero: num (número) y answer (respuesta) }
31+ begin
32+ num := StrToInt(edtInput.Text); { Convierte la cadena a entero y se lo asigna a la variable num }
33+ // Se requiere esto con Lazarus en x86, definimos el modo ensamblador de Intel:
34+ {$ASMMODE intel}
35+ asm
36+ MOV EAX, num
37+ ADD EAX, 110B //sumar el numero 110 binario (6 en decimal) al contenido del registro EAX.
38+ SUB EAX, 2 //restar o substraer el número 2 decimal (no lleva la B de binario) al contenido del registro EAX.
39+ MOV answer, EAX //mover el contenido de EAX a la variable answer.
40+ end;
41+ edtOutput.Text := IntToStr(answer); { Convierte el número entero a su equivalente en cadena & pasa a la propiedad texto }
42+ end;
43+
44+ initialization
45+ {$I unit_asm.lrs}
46+ end.
47+```
48+
49+   En el siguiente enlace podéis encontrar una muy buena descripción al respecto en la documentación de FreePascal:
50+
51+- [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:
52+
53+` $ASMMODE : Modo ensamblador (Intel 80x86 solamente)`
54+
55+   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:
56+
57+- **att:** Indica que los bloques asm contienen sintaxis en la modalidad ensamblador de AT&T.
58+
59+- **intel:** Indica que los bloques asm contienen sintaxis en la modalidad ensamblador de Intel.
60+
61+- **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.
62+
63+   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.
64+
65+   En el IDE de Lazarus podemos encontrar estas opciones para el proyecto en curso:
66+
67+   El interprete de ensamblador predeterminado, si no se especifica otro, es AT&T.
68+
69+   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:
70+
71+``` pascal
72+ var
73+ I : Integer;
74+ begin
75+ I:=3;
76+ asm
77+ movl I,%eax
78+ end;
79+ end;
80+```
81+
82+   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.
83+
84+   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 :
85+
86+``` pascal
87+ {$ASMMODE att} // pero recordar que es el que utiliza por defecto si no se especifica otro
88+ function geteipasebx : pointer;assembler;
89+ asm
90+ movl (%esp),%ebx
91+ ret
92+ end;
93+```
94+
95+   Es posible todavía declarar variables para el procedimiento en ensamblador:
96+
97+``` pascal
98+ procedure Move(const source;var dest;count:SizeInt);assembler;
99+ var
100+ saveesi,saveedi : longint;
101+ asm
102+ movl %edi,saveedi
103+ end;
104+```
105+
106+   El compilador reservará espacio en la pila para estas variables, esto inserta algunos comandos para ello.
107+
108+   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:
109+
110+``` pascal
111+
112+function geteipasebx : pointer;assembler;[alias:’FPC_GETEIPINEBX’];
113+ asm
114+ movl (%esp),%ebx
115+ ret
116+ end;
117+```
118+
119+   Para hacer que la función esté disponible en código ensamblador fuera de la unidad actual debemos añadir el modificador **public**:
120+
121+``` pascal
122+
123+function geteipasebx : pointer;assembler;[public,alias:’FPC_GETEIPINEBX’];
124+ asm
125+ movl (%esp),%ebx
126+ ret
127+ end;
128+```
129+
130+---
131+*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