Связь ассемблера с языками высокого уровня

Оптимизация с использованием языка низкого уровня ассемблера. Его связь с языками высокого уровня. Отдельно компилируемые модули. Разработка программных модулей на ассемблере с использованием компиляторов TASM5.0 фирмы Borlandи MASM6.14 фирмы Microsoft.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 18.05.2014
Размер файла 405,5 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru

Размещено на http://www.allbest.ru

Оглавление

Оптимизация приложений при помощи ассемблера

Оптимизация с использованием языка низкого уровня ассемблера

Связь ассемблера с языками высокого уровня

Отдельно компилируемые модули

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

Оптимизация приложений при помощи ассемблера

Большинство разработчиков понимает, что в условиях жесткой конкуренции вопрос производительности является важнейшим условием успеха или неудачи программы на рынке программных продуктов. Без серьезной работы над улучшением производительности программного кода нельзя обеспечить конкурентоспособность приложения. Хотя все осознают необходимость и важность процесса оптимизации программного обеспечения, эта тема до сих пор является противоречивой и дискуссионной. Все споры вокруг этого процесса в основном затрагивают один вопрос: так ли уж необходимо программисту заниматься ручной оптимизацией своего приложения, если для этого есть готовые аппаратно-программные средства?

Часть программистов считает, что улучшить производительность работы приложения без использования средств отладки самого компилятора нельзя, тем более что все современные компиляторы имеют встроенные(built-in) средства оптимизации программного кода. Можно полностью положиться на компилятор, который сгенерирует для вас оптимальный код, и вообще не заниматься улучшением качества программы. При этом в целом ряде случаев может и не понадобиться никаких доработок и улучшений. Например, при создании небольших офисных приложений или утилит тестирования сети оптимизация обычно не нужна.

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

Если программист разрабатывает программы, работающие в реальном времени, такие как драйверы устройств, системные службы или промышленные приложения, то без очень серьезной работы по ручной доводке кода до оптимальной производительности задача написания программы просто не будет выполнена. И дело здесь не в том, что средства разработки несовершенны и не обеспечивают того уровня оптимизации, какой от них требуется. Любая более или менее серьезная программа имеет столько взаимосвязанных параметров, что ни одно средство разработки не улучшит ее так, как это может сделать сам программист. Процесс оптимизации программ сродни скорее искусству, чем "чистому" программированию, и трудно поддается алгоритмизации.

Улучшение производительности программ -- процесс обычно трудоемкий, занимающий значительную часть времени. Хочется отметить, что не существует единого критерия оптимизации. Более того, сам процесс оптимизации довольно противоречив. Например, если добиться уменьшения объема памяти, используемого программой, то за это придется расплатиться потерей быстродействия работы программы.

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

Хорошие программы обычно сочетают те или иные качества в разумных пропорциях, в зависимости от того, что важнее: скорость выполнения, размер программы (как файла приложения, так и объема памяти, занимаемого работающим приложением) или удобство интерфейса пользователя.

Для многих офисных приложений очень важным показателем является удобство интерфейса пользователя и как можно более высокая функциональность. Например, для пользователя программы электронного телефонного справочника тот факт, что программа работает на 10% быстрее или медленнее, особого значения не имеет. Размер такой программы, в принципе, не критичен и также не имеет особого значения, т. к. объем современных жестких дисков достаточно большой, чтобы поместить десятки и даже сотни таких электронных справочников. Программе может быть необходимо десятки мегабайт оперативной памяти для работы -- это тоже сейчас не проблема. Но вот возможность удобной манипуляции данными для пользователя будет очень важной.

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

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

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

Простейший способ заставить приложения работать быстрее -- это повысить вычислительную мощь компьютера за счет установки более производительного процессора или увеличения объема памяти, т. е. сделать апгрейд (upgrade) аппаратной части. В этом случае проблема производительности будет решена сама собой.

Однако многие ожидания насчет производительности новых поколений процессоров, новых типов памяти и архитектур системных шин оказываются явно преувеличенными. Их производительность на практике оказывается ниже задекларированной фирмами-изготовителями. Так, например, новые микросхемы памяти, как правило, превосходят своих предшественников по объему хранимых данных, но отнюдь не по быстродействию. Производительность жестких дисков также растет медленнее, чем их объем.

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

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

Далее мы будем рассматривать только алгоритмические и программные методы повышения производительности работы приложений.

Оптимизация может проводиться по следующим направлениям:

тщательная проработка алгоритма разрабатываемой программы;

учет существующих аппаратных средств компьютера и использование их оптимальным образом;

использование средств языка высокого уровня той среды, в которой разрабатывается приложение;

использование языка низкого уровня ассемблера;

учет специфических особенностей процессора.

В данной курсовой работе подробно рассматривается использование языка низкого уровня ассемблера, и его взаимосвязь с языками высокого уровня.

Оптимизация с использованием языка низкого уровня ассемблера

Использование языка ассемблера во многом решает проблему избыточности программного кода. Ассемблерный код более компактен, чем его аналог на языке высокого уровня. Сгенерированный компилятором языка высокого уровня ассемблерный код даже с использованием опций оптимизации не устраняет избыточность кода приложения. В то же время язык ассемблера позволяет разрабатывать короткий и эффективный код.

Программный модуль на ассемблере обладает, как правило, более высоким быстродействием, чем написанный на языке высокого уровня. Это связано с меньшим числом команд, требуемых для реализации фрагмента кода. Меньшее число команд быстрее выполняется центральным процессором, что, соответственно, повышает производительность программы.

Можно разрабатывать отдельные модули полностью на ассемблере и присоединять их к программам на языке высокого уровня. Также можно использовать мощные встроенные средства языков высокого уровня для написания ассемблерных процедур непосредственно в теле основной программы. Такие возможности предусмотрены во всех языках высокого уровня. Эффективность использования встроенного ассемблера может быть очень высока. Встроенный ассемблер позволяет добиваться максимального эффекта при оптимизации математических выражений, программных циклов и обработки массивов данных в основной программе.

Связь ассемблера с языками высокого уровня

В основном программисты пишут на одном из двух языков высокого уровня: Pascalили C++. Современные средства быстрого проектирования с использованием C++ и Pascal, такие как MicrosoftVisualStudio.NET, BorlandC++ Builder 6 и BorlandDelphi 7, пользуются наибольшей популярностью среди программистов. Исходя из этого решено использовать для демонстрации основных принципов построения интерфейсов две среды программирования двух наиболее ярких представителей на рынке программных средств проектирования -- MicrosoftVisualC++ .NETи BorlandDelphi 7.

Программные модули на ассемблере мы будем разрабатывать с использованием компиляторов TASM5.0 фирмы Borlandи MASM6.14 фирмы Microsoft.

В общем случае командная строка для компилятора TASMвыглядит так:

tasm32 /ml<имя_файла.asm><имя_файла.obj>

Если используется MASM, командная строка для компилятора будет выглядеть следующим образом:

ml/с /Fo<имя_файла.obj><имя_файла.asm>

Никакие дополнительные опции компиляторов для получения файлов с расширением .OBJне нужны.

При решении этой задачи программист должен учитывать следующее:

правила согласования имен идентификаторов (переменных и процедур), помещенных в объектные файлы. Компилятор языка высокого уровня может изменять или нет оригинальные имена в объектном модуле, поэтому важно знать, происходит ли такое изменение и как;

модель памяти, используемую ассемблерным модулем(tiny, small, compact, medium, huge, large,flat);

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

нужно ли сохранять регистры в подпрограмме? Если да, то какие;

порядок передачи параметров вызываемой подпрограмме;

метод передачи параметров в подпрограмму (с использованием регистров, стека, разделяемой памяти);

способ передачи параметров в вызываемую подпрограмму (по значению или по ссылке);

если передача параметров подпрограмме осуществляется через стек, то как должен восстанавливаться указатель стека -- вызывающей или вызываемой подпрограммой;

метод возвращения значения в вызывающую подпрограмму (через стек, регистры или общую область памяти).

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

Следующий момент -- модели памяти, используемые внешними подпрограммами. Для 32-разрядных приложений используется только одна модель памяти -- flat. Она поддерживается как компилятором Pascal, так и C++. ассемблер язык программный модуль

Что касается параметров вызова внешних подпрограмм, то для 32-разрядных приложений параметры в вызываемую процедуру передаются одним из двух способов: либо по значению, либо по ссылке. При передаче параметра по значению в процедуру передается непосредственно сам 32-разрядный операнд, а при передаче по ссылке -- адрес (тоже 32-разрядное значение) этого операнда.

Все параметры являются 32-разрядными. Понятия "ближняя ссылка" и "дальняя ссылка" не различаются! Все ссылки в адресном пространстве 32-разрядных приложений являются "ближними". Например, не имеет смысла объявлять подпрограммы как nearили far:

MyProc PROC NEAR или

MyProc PROC FAR

поскольку компилятор все равно интерпретирует все вызовы как ближние.

Для такой модели не существует отдельных сегментов данных и кода. Пространство адресов считается линейным, и в нем располагаются код и данные, которые используют 32-разрядные смещения, а вызовы процедур и функций считаются ближними. Такой режим работы обеспечивает высокую производительность 32- разрядных приложений, т. к. нет преобразования "сегмент-смещение" в абсолютные адреса. Кроме того, 32-разрядные приложения "не видят" друг друга и выполняются в изолированном от других приложений пространстве адресов. Это очень сильно отличает их от 16-разрядных приложений, где все программы могли "видеть" друга.

Параметры в вызываемую процедуру передаются через стек или через регистры. Все варианты передачи параметров через стек или регистры представлены в табл.1.

Таблица 1. Варианты передачи параметров

Директива

Порядок передачи параметров

Освобождение

стека

Передача параметров через регистры

register, fastcall

fastcall

Слева направо

Процедура

ЕАХ, EDX, ЕСХ

pascal

Слева направо

Процедура

Нет

cdecl

Справа налево

Вызывающая

программа

Нет

stdcall

Справа налево

Процедура

Нет

safecall

Справа налево

Процедура

Нет

Порядок передачи параметров для каждой директивы указывает компилятору, каким образом параметры передаются в вызываемую процедуру. Для директив pascal, cdecl, stdcallи safecallпараметры передаются через стек, а при использовании директив registerили fastcall-- через регистры.

Перед возвращением в основную программу необходимо восстановить указатель стека. Это относится кдирективам pascal, cdecl, stdcallиsafecall. Что касается применения тех или иных способов вызова внешних процедур, то здесь не существует однозначных рецептов. Если вы работаете с APIфункциями Windows, то для них стандартным способом вызова является stdcallили safecall. Директиву cdeclлучше использовать для вызова процедур и функций из программ, написанных в C++.

Наиболее быстрым способом передачи параметров является регистровый(register, или fastcall). Директива registerиспользуется в большинстве языков высокого уровня, но разработчики Microsoftрешили назвать ее по- другому, и в VisualC++ она определяется иначе -- fastcall. Стек в этом случае не используется, поэтому мы получаем выигрыш по скорости выполнения подпрограммы.

Директива pascalиспользуется редко и только в целях обратной совместимости(backwardcompatibility).

Все подпрограммы возвращают результат (значение или адрес) в регистре ЕАХ.

Отдельно компилируемые модули

Разработаем программу на языке высокого уровня, вызывающую процедуру subtwo (передача параметров через стек, по значению).

Delphi 7:

stpas.pas

unitstpas;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

I1Edit: TEdit;

Label1: TLabel;

I2Edit: TEdit;

Label2: TLabel;

subResult: TEdit;

Label3: TLabel;

Button1: TButton;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

{$L subtwo.obj}

functionsubtwo(i1:Integer; i2:Integer):Integer;stdcall;external;

procedure TForm1.Button1Click(Sender: TObject);

var

I1, I2: Integer;

begin

I1:= StrToInt(I1Edit.Text);

I2:= StrToInt(I2Edit.Text);

subResult.Text:= IntToStr(subtwo(I1, I2));

//

end;

end.

subtwo.asm

.386

.model flat

publicsubtwo

.data

.code

subtwoproc

pushEBP

movEBP, ESP

movEAX, DWORD PTR [EBP+8]

subEAX, DWORD PTR [EBP+12]

popEBP

ret8

subtwoendp

end

Скриншот:

Microsoft Visual C++ . Net:

SUBSTRACTION TWO INTS IN C.NETDlg.cpp

#include "stdafx.h"

#include "SUBSTRACTION TWO INTS IN C.NET.h"

#include "SUBSTRACTION TWO INTS IN C.NETDlg.h"

extern "C" int _stdcallsubtwo(int i1, int i2);

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

// CAboutDlg dialog used for App About

classCAboutDlg : public CDialog

{

public:

CAboutDlg();

// Dialog Data

enum { IDD = IDD_ABOUTBOX };

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

// Implementation

protected:

DECLARE_MESSAGE_MAP()

};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

}

voidCAboutDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

END_MESSAGE_MAP()

// CSUBSTRACTIONTWOINTSINCNETDlg dialog

CSUBSTRACTIONTWOINTSINCNETDlg::CSUBSTRACTIONTWOINTSINCNETDlg(CWnd* pParent /*=NULL*/)

: CDialog(CSUBSTRACTIONTWOINTSINCNETDlg::IDD, pParent)

, I1(0)

, I2(0)

, iSubResult(0)

{

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

voidCSUBSTRACTIONTWOINTSINCNETDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

DDX_Text(pDX, IDC_EDIT1, I1);

DDX_Text(pDX, IDC_EDIT2, I2);

DDX_Text(pDX, IDC_EDIT3, iSubResult);

}

BEGIN_MESSAGE_MAP(CSUBSTRACTIONTWOINTSINCNETDlg, CDialog)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

//}}AFX_MSG_MAP

ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)

END_MESSAGE_MAP()

// CSUBSTRACTIONTWOINTSINCNETDlg message handlers

BOOL CSUBSTRACTIONTWOINTSINCNETDlg::OnInitDialog()

{

CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)

{

CStringstrAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

}

}

// Set the icon for this dialog. The framework does this automatically

// when the application's main window is not a dialog

SetIcon(m_hIcon, TRUE);// Set big icon

SetIcon(m_hIcon, FALSE);// Set small icon

// TODO: Add extra initialization here

return TRUE; // return TRUE unless you set the focus to a control

}

voidCSUBSTRACTIONTWOINTSINCNETDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

if ((nID& 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlgdlgAbout;

dlgAbout.DoModal();

}

else

{

CDialog::OnSysCommand(nID, lParam);

}

}

// If you add a minimize button to your dialog, you will need the code below

// to draw the icon. For MFC applications using the document/view model,

// this is automatically done for you by the framework.

voidCSUBSTRACTIONTWOINTSINCNETDlg::OnPaint()

{

if (IsIconic())

{

CPaintDCdc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// Center icon in client rectangle

intcxIcon = GetSystemMetrics(SM_CXICON);

intcyIcon = GetSystemMetrics(SM_CYICON);

CRectrect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialog::OnPaint();

}

}

// The system calls this function to obtain the cursor to display while the user drags

// the minimized window.

HCURSOR CSUBSTRACTIONTWOINTSINCNETDlg::OnQueryDragIcon()

{

returnstatic_cast<HCURSOR>(m_hIcon);

}

voidCSUBSTRACTIONTWOINTSINCNETDlg::OnBnClickedButton1()

{

// TODO: Add your control notification handler code here

UpdateData(TRUE);

iSubResult = subtwo(I1, I2);

UpdateData(FALSE);

}

subtwo.asm

.386

.model flat

public _subtwo@8

.data

.code

_subtwo@8 proc

pushEBP

movEBP, ESP

movEAX, DWORD PTR [EBP+8]

subEAX, DWORD PTR [EBP+12]

popEBP

ret8

_subtwo@8 endp

end

Найти максимальное значение в массиве целых чисел (передача параметров через стек, по ссылке).

Delphi 7:

fmaxpas.pas

unitfmaxpas;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Button1: TButton;

Edit1: TEdit;

Edit2: TEdit;

Label1: TLabel;

Label2: TLabel;

procedure Button1Click(Sender: TObject);

procedureFormCreate(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

I1:array [1..12] of integer = (585,1751,-27,-76,312, 93, 5, -1, 57, 22,-5, 997);

SI1: Integer;

pMax: PInteger;

Max: Integer;

implementation

{$R *.dfm}

{$L maxint.obj}

functionmaxint(PI1:PInteger;SI1:Integer):PInteger;stdcall;external;

procedure TForm1.Button1Click(Sender: TObject);

begin

pMax:= maxint(@I1,SI1);

Max:=pMax^;

Edit2.Text:= IntToStr(Max);

end;

procedure TForm1.FormCreate(Sender: TObject);

var

Cnt:Integer;

begin

SI1:= SizeOf(I1) div 4;

forCnt:= 1 to SI1 do

Edit1.Text:= Edit1.Text + ' ' + IntToStr(I1[Cnt]);

end;

end.

maxint.asm

.386

.model flat

publicmaxint

.data

.code

maxintproc

pushESI

pushEBP

movEBP, ESP

movEDX, DWORD PTR [EBP+16] ; first.parm - right - size

movESI, DWORD PTR [EBP+12] ; sec.parm - left - address of array

next_cmp:

movEAX, DWORD PTR [ESI]

cmpEAX, DWORD PTR [ESI+4]

jledec_cnt

xchgEAX, DWORD PTR [ESI+4]

dec_cnt:

decEDX

cmpEDX, 0

jefin

addESI, 4

jmpnext_cmp

fin:

movEAX, ESI

;

popEBP

popESI

ret8

maxintendp

end

Microsoft Visual C++ . Net:

Find Max Integer in ArrayDlg.cpp

#include "stdafx.h"

#include "Find Max Integer in Array.h"

#include "Find Max Integer in ArrayDlg.h"

extern "C" int* _stdcallmaxval(int *pi1, int si1);

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

// CAboutDlg dialog used for App About

classCAboutDlg : public CDialog

{

public:

CAboutDlg();

// Dialog Data

enum { IDD = IDD_ABOUTBOX };

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

// Implementation

protected:

DECLARE_MESSAGE_MAP()

};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

}

voidCAboutDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

END_MESSAGE_MAP()

// CFindMaxIntegerinArrayDlg dialog

CFindMaxIntegerinArrayDlg::CFindMaxIntegerinArrayDlg(CWnd* pParent /*=NULL*/)

: CDialog(CFindMaxIntegerinArrayDlg::IDD, pParent)

{

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

voidCFindMaxIntegerinArrayDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CFindMaxIntegerinArrayDlg, CDialog)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

//}}AFX_MSG_MAP

//ON_WM_CREATE()

//ON_WM_ACTIVATE()

ON_WM_LBUTTONDOWN()

END_MESSAGE_MAP()

// CFindMaxIntegerinArrayDlg message handlers

BOOL CFindMaxIntegerinArrayDlg::OnInitDialog()

{

CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)

{

CStringstrAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

}

}

// Set the icon for this dialog. The framework does this automatically

// when the application's main window is not a dialog

SetIcon(m_hIcon, TRUE);// Set big icon

SetIcon(m_hIcon, FALSE);// Set small icon

// TODO: Add extra initialization here

return TRUE; // return TRUE unless you set the focus to a control

}

voidCFindMaxIntegerinArrayDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

if ((nID& 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlgdlgAbout;

dlgAbout.DoModal();

}

else

{

CDialog::OnSysCommand(nID, lParam);

}

}

// If you add a minimize button to your dialog, you will need the code below

// to draw the icon. For MFC applications using the document/view model,

// this is automatically done for you by the framework.

voidCFindMaxIntegerinArrayDlg::OnPaint()

{

if (IsIconic())

{

CPaintDCdc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// Center icon in client rectangle

intcxIcon = GetSystemMetrics(SM_CXICON);

intcyIcon = GetSystemMetrics(SM_CYICON);

CRectrect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialog::OnPaint();

}

}

// The system calls this function to obtain the cursor to display while the user drags

// the minimized window.

HCURSOR CFindMaxIntegerinArrayDlg::OnQueryDragIcon()

{

returnstatic_cast<HCURSOR>(m_hIcon);

}

voidCFindMaxIntegerinArrayDlg::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

int i1[10] = {674, 7, 90, -34, 2, -596, -45, 76, -12, 64};

charbuf[8];

CClientDCdc(this);

RECT rect;

GetClientRect(&rect);

for (intcnt = 0;cnt <sizeof(i1)/4;cnt++)

{

dc.TextOut((rect.right - rect.left)/30 + cnt*45 , (rect.bottom - rect.top )/ 4 , itoa(i1[cnt],buf,10));

};

intires = *maxval(i1, sizeof(i1)/4);

dc.TextOut((rect.right - rect.left)/2 - 40 , (rect.bottom - rect.top )/2 + 30 , itoa(ires, buf,10));

CDialog::OnLButtonDown(nFlags, point);

}

maxval.asm

.386

.model flat

public _maxval@8

.data

MaxVal DD 0

.code

_maxval@8 proc

pushESI

pushEBP

movEBP, ESP

movECX, DWORD PTR [EBP+16]

decECX

movESI, DWORD PTR [EBP+12]

movEAX, [ESI]

next_cmp:

cmpEAX, [ESI+4]

jggo_loop

movEAX, [ESI+4]

go_loop:

addESI, 4

loopnext_cmp

movDWORD PTR MaxVal, EAX

movEAX, OFFSET MaxVal

popEBP

popESI

ret8

_maxval@8 endp

end

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

Найти сумму двух целых чисел:

basm1pas.pas

unit basm1pas;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Button1: TButton;

Edit1: TEdit;

Label1: TLabel;

Edit2: TEdit;

Edit3: TEdit;

Label2: TLabel;

Label3: TLabel;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

I1, I2: Integer;

implementation

{$R *.dfm}

functionAddTwo(i1, i2:PInteger):PInteger;

var

ires:Integer;

begin

asm

push ESI

mov EAX, dwordptr i1

lea ESI, dwordptrires

mov EAX, [EAX]

mov ECX, dwordptr i2

add EAX, [ECX]

movdwordptr [ESI], EAX

mov @Result, ESI

pop ESI

end;

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

I1:= StrToInt(Edit1.Text);

I2:= StrToInt(Edit2.Text);

Edit3.Text:= IntToStr(AddTwo(@I1, @I2)^);

end;

end.

Скриншот:

Найти сумму элементов в массиве:

Summa of RealsDlg.cpp

#include "stdafx.h"

#include "Summa of Reals.h"

#include "Summa of RealsDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

// CAboutDlg dialog used for App About

classCAboutDlg : public CDialog

{

public:

CAboutDlg();

// Dialog Data

enum { IDD = IDD_ABOUTBOX };

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

// Implementation

protected:

DECLARE_MESSAGE_MAP()

};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

}

voidCAboutDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

END_MESSAGE_MAP()

// CSummaofRealsDlg dialog

CSummaofRealsDlg::CSummaofRealsDlg(CWnd* pParent /*=NULL*/)

: CDialog(CSummaofRealsDlg::IDD, pParent)

, s_Array(_T(""))

, f_Summa(0)

{

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

voidCSummaofRealsDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

DDX_Text(pDX, IDC_EDIT1, s_Array);

DDX_Text(pDX, IDC_EDIT2, f_Summa);

}

BEGIN_MESSAGE_MAP(CSummaofRealsDlg, CDialog)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

//}}AFX_MSG_MAP

ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)

END_MESSAGE_MAP()

// CSummaofRealsDlg message handlers

BOOL CSummaofRealsDlg::OnInitDialog()

{

CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)

{

CStringstrAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

}

}

// Set the icon for this dialog. The framework does this automatically

// when the application's main window is not a dialog

SetIcon(m_hIcon, TRUE);// Set big icon

SetIcon(m_hIcon, FALSE);// Set small icon

// TODO: Add extra initialization here

return TRUE; // return TRUE unless you set the focus to a control

}

voidCSummaofRealsDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

if ((nID& 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlgdlgAbout;

dlgAbout.DoModal();

}

else

{

CDialog::OnSysCommand(nID, lParam);

}

}

// If you add a minimize button to your dialog, you will need the code below

// to draw the icon. For MFC applications using the document/view model,

// this is automatically done for you by the framework.

voidCSummaofRealsDlg::OnPaint()

{

if (IsIconic())

{

CPaintDCdc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// Center icon in client rectangle

intcxIcon = GetSystemMetrics(SM_CXICON);

intcyIcon = GetSystemMetrics(SM_CYICON);

CRectrect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialog::OnPaint();

}

}

// The system calls this function to obtain the cursor to display while the user drags

// the minimized window.

HCURSOR CSummaofRealsDlg::OnQueryDragIcon()

{

returnstatic_cast<HCURSOR>(m_hIcon);

}

float* CSummaofRealsDlg::sumReals(float* farray, int lf)

{

floatfsum;

_asm {

mov ESI, farray

mov ECX, lf

dec ECX

finit

fldz

fld [ESI]

next:

add ESI, 4

fadd [ESI]

loop next

fstpfsum

fwait

lea EAX, fsum

};

}

voidCSummaofRealsDlg::OnBnClickedButton1()

{

// TODO: Add your control notification handler code here

floatfarray[] = {2.4, 5.9, -4.12, 3.12, -8.45};

intfsize = sizeof(farray)/4;

//

CStringstmp;

//

UpdateData(TRUE);

stmp.Empty;

for (intcnt = 0; cnt<fsize; cnt++)

{

stmp.Format("%.2f", farray[cnt]);

s_Array = s_Array + " " + stmp;

};

//

f_Summa = *sumReals(&farray[0], fsize);

UpdateData(FALSE);

}

Скриншот:

Размещено на Allbest.ru


Подобные документы

  • Структурные подразделения и отделы организации, ее технические программные средства. Разработка приложений обработки данных на ассемблере, языке программирования высокого уровня. Тестирование и оптимизация программных модулей. Разработка документации.

    отчет по практике [175,0 K], добавлен 30.09.2022

  • Взаимосвязь стадий процесса проектирования сложных программных систем. Создание компилятора подмножества языка высокого уровня (Pascal) на язык Ассемблера. Структура входных и выходных данных, алгоритмы их обработки. Рабочая документация программы.

    курсовая работа [256,7 K], добавлен 27.07.2014

  • Разработка комплекса алгоритмов. Кодирование и компиляция. Тестирование, отладка, испытание и сдача программы. Минимальные системные требования для использования Delphi 7. Написание программы с использованием инструментального языка высокого уровня.

    курсовая работа [2,7 M], добавлен 21.02.2011

  • Особенности ассемблера - машинно-ориентированного языка низкого уровня, применяемого для создания простых приложений. Связывание программ на разных языках. Типичный формат записи команд, инструкции и директивы языка ассемблера. Разработка игры "Змейка".

    курсовая работа [215,0 K], добавлен 20.07.2014

  • Создание программы с использованием принципов объектно-ориентированного программирования на языке высокого уровня С# средствами Microsoft Visual Studio 2010. Построение алгоритма реализации. Определение математического аппарата, применение его в задаче.

    курсовая работа [500,4 K], добавлен 13.01.2015

  • Методы грамматического разбора при разработке учебного транслятора. Проектирование лексического анализатора и магазинного автомата. Программная реализация синтаксического анализатора текстового языка высокого уровня. Разработка модуля интерпретации.

    курсовая работа [697,2 K], добавлен 06.01.2013

  • Построение компилятора с языка высокого уровня как одного из элементов системы программирования. Разработка компилятора ассемблера, модификация базы данных исходного макета. Загрузчик, эмулятор, отладчик. Использование Flex и Bison для программирования.

    курсовая работа [599,0 K], добавлен 04.11.2014

  • Транслятор как программа или техническое средство, выполняющее трансляцию программы. Рассмотрение основных особенностей постройки лексического анализатора. Знакомство с этапами разработки транслятора с ограниченного подмножества языка высокого уровня.

    курсовая работа [580,5 K], добавлен 06.08.2013

  • Методы численного интегрирования. Характеристика основных составляющих структурного программирования. Решение задания на языке высокого уровня Паскаль. Построение графического решения задачи в пакете Matlab. Решение задания на языке высокого уровня C.

    курсовая работа [381,7 K], добавлен 10.05.2018

  • Программная реализация настольного приложения с использованием языка программирования C#. Проектирование и структура пользовательского интерфейса, требования к нему и оценка функциональности. Разработка руководства пользователя и его использование.

    курсовая работа [297,6 K], добавлен 10.03.2015

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.