Блоґ одного кібера

Історія хвороби контуженого інформаційним вибухом

Ассемблер в Visual C++

leave a comment »

Вчитися програмувати на ассемблері важко, бо щоб написати програму яка видає хоч якийсь результат (типу „Привіт світ!”) потрібно дуже багато знати. Ввід і вивід в ассемблері пов’язаний з складними функціями API, викликати які — велика морока. Крім того більшість компіляторів — консольні набори з компілятора, лінкера, дебагера, які потрібно запускати з складними параметрами командного рядка і окремо. Але є набагато простіший спосіб вивчення ассемблера, для таких чайників як і я.

Для цього не потрібно нічого, крім знайомого Visual C++. Можна навіть щось інше, навіть древній Turbo C, але там взаємодія з підпрограмами може бути інша, крім того навчитися програмувати для систем i386, можна тільки в 32 розрядних середовищах. Чим добре Visual C++? Тут не потрібно абсолютно все писати на ассемблері. Ввід і вивід можна здійснювати за допомогою зручних scanf і printf.

Досить вступів, думаю можна перейти до теорії. Часто можна почути слова x86, i386 сумісність. Це слово означає, що програма виконується на даній і всіх наступних архітектурах. Я вже згадував про архітектури до i386. В архітектурі x86 (процесор 8086), були 16 розрядні регістри ax,bx, cx, dx. В 32 розрядній архітектурі i386 їх було розширено, і до імені додали e (extended). Проте старі назви все ще залишились, для досягнення сумісності. Також, можна було отримувати доступ до окремих байтів регістру за допомогою букв h (hi – старший) l (lo – молодший). Загалом до того що міститься скажімо в регістрі eax можна було дістатись за такими іменами: eax,ax,ah,al. Ось маленька схемка:

Регістр eax/ax/ah/al.

А тепер краще не покладатись на слова, а перевірити все на практиці. Відкриваємо студію, і створюємо новий консольний проект

#include <stdlib.h> //Підключаємо стандартні бібліотеки
#include <stdio.h>

unsigned int LoWord(unsigned int a) // Підпрограма написана на ассемблері
{
	_asm // така директива каже компілятору, що після неї іде оператор на ассемблері. 
	{  //(або кілька операторів, якщо в дужках.
		mov eax,a; // Переносимо значення зі змінної а в регістр eax
		mov ebx,0; // Ініціалізуємо ebx нулем
		mov bx,ax; // Переносимо значення з ax в bx
		mov a,ebx; // Тепер записуємо значення ebx назад в а
	};
	return a; // Повертаємо результат функції
}

unsigned int LoByte(unsigned int a)
{
	_asm
	{
		mov ebx,a;
		mov eax,0; 
		mov al,bl; // Переміщуємо молодщий байт ax в bx
	}
	//Тут я забув написати return, але нічого страшного. Результат по замовчуванню береться з eax
}

int main(void)
{
	unsigned int x; // Можна і зі знаком, але давайте зробимо все простіше
	scanf("%X",&x); // Вводимо натуральне 32 розрядне число в шіснадцятковій системі
	printf("\n Lo word (ax): %X\n",LoWord(x)); // і виводимо молодше слово числа
	printf("\n Lo byte (al): %X\n",LoByte(x)); // і виводимо молодше слово числа
	system("pause"); // Почекати поки користувач побачить результат
	return 0;
}

Приклад, як для привітання зі світом, трохи заскладний, зате ілюстративний. Використовується шістнадцядкова система, тому для заповнення всіх 32 бітів, потрібно ввести 8 цифр. Програма занесе їх в eax, і виведе вміст ax і al.

От і все. Розберусь більше — напишу більше.

Advertisements

Written by bunyk

Березень 18, 2009 at 22:39

Оприлюднено в Кодерство

Tagged with ,

Залишити відповідь

Заповніть поля нижче або авторизуйтесь клікнувши по іконці

Лого WordPress.com

Ви коментуєте, використовуючи свій обліковий запис WordPress.com. Log Out / Змінити )

Twitter picture

Ви коментуєте, використовуючи свій обліковий запис Twitter. Log Out / Змінити )

Facebook photo

Ви коментуєте, використовуючи свій обліковий запис Facebook. Log Out / Змінити )

Google+ photo

Ви коментуєте, використовуючи свій обліковий запис Google+. Log Out / Змінити )

З’єднання з %s

%d блогерам подобається це: