Программа, которая использует функцию stdcall get_str_length с асемблерной вставкой, для нахождения длины ASCIIZ-строки.

Пример использования директивы ASM и команд сопроцессора в программе на языке Паскаль (Delphi 5.0).

Примеры

Встроенный ассемблер

В ассемблерном модуле в регистре EAX возвращается значение, которое может быть либо числом, либо указателем на некую переменную или структуру. Если возвращаемое число типа WORD, то оно содержится в младшем слове регистра EAX.

Тип возвращаемых функцией данных

Когда происходит взаимодействие ассемблерного модуля с языками высокого уровня, это необходимо учитывать и знать, как работают те или иные соглашения.

Согласование параметров

В таблице ниже представлены основные соглашения по передаче параметров в процедуру.

Ранее во всех ассемблерных программах указывался тип передачи параметров как stdcall. Однако, это никак и нигде не использовалось - так как передача и извлечение параметров делалась явно, без помощи транслятора.

Таблица, представляющая соглашения о вызовах

Соглашение Параметры Очистка стека Регистры
Pascal (конвенция языка Паскаль) Слева направо Процедура Нет
Register (быстрый или регистровый вызов) Слева направо Процедура Задействованы три регистра (EAX,EDX,ECX), далее стек
Cdecl (конвенция С) Справа налево Вызывающая программа Нет
Stdcall (стандартный вызов) Справа налево Процедура Нет

 


Встроенные ассемблеры часто несколько отстают от обычных ассемблеров в части поддержки новых команд микропроцессоров. Это вполне объяснимо, так как разработка новой версии пакета, скажем C++ Builder, требует гораздо больше времени, чем пакета TASM.

Ассемблерные вставки (inline-ассемблер) используются в двух случаях:

1. Если нужно оптимизировать критичные по скорости и небольшие по объему участки программы. Грамотно написанный ассемблерный код всегда быстрее кода, который генерируется компилятором С++ или Delphi.

2. Нужен прямой доступ к памяти и портам. Чаще всего используется в драйверах, так как из третьего кольца защиты с портами не очень-то поработаешь.

 


program Project2;{$APPTYPE CONSOLE}uses SysUtils;var d:double;function soproc(f:double): double;var res:double;begin asm FLD f FSIN FSTP res end; soproc:=res;end; begin d:=-pi; while (d<=pi) do begin writeln(d:10:2,'-',soproc(d):10:2); d:=d+0.1; end;end.

 

 


2) Пример использования директивы ASM и команд сопроцессора в программе на языке Си (Borland C++ 5.0).

#include <windows.h>#include <stdio.h>double soproc(double f); void main(){ double w=-3.14; while(w<=3.14) { printf("%f- %f\n", w, soproc(w)); w=w+0.1; } ExitProcess(0);} double soproc(double f){ double d; asm { FLD f FSIN FSTP d } return d;}

 


 

#include "stdafx.h"

int _stdcall get_str_length(char *inputstr)

{

__asm{

 

mov edi, inputstr

mov esi, edi

mov ecx, -1

xor al, al

cld

repne scasb

sub edi, esi

; Результат работы функции следует возвращать в eax.

mov eax, edi

dec eax

}

}

 

int main()

{

char str_1[]="Hello, world! My name is Alex...";

int i;

i = get_str_length(str_1);

printf("String: %s\nLength: %d", str_1, i);

printf("\n");

return 0;

}

 


4) Программа, которая складывает два числа в десятичной системе исчисления и выдаёт результат тоже в десятичной системе исчисления. (Example2)

 

#include "stdafx.h"

 

int main()

{

int a = 120;

int b = 159;

int c;

 

__asm{

mov eax, a

mov ebx, b

add eax, ebx

mov c, eax

}

printf("a + b = %d + %d = %d\n", a, b, c);

return 0;

}