Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.09.2012, 14:25   #1
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию Примеры программ на языке ассемблера Intel® 64 и IA-32

В этой теме я буду выкладывать примеры программ на языке ассемблера Intel® 64 и IA-32. Для демонстрации работы с WinAPI и языком ассемблера.

Перед тем как выкладывать демо-программы, опишу работу с инструментарием:
сборщик - MASM
отладчик- Ollydbg
оболочка - FAR

Пока ограничусь MASM (далее возможны другие сборщики) и IA-32.

Скачиваем инструментарий:

MASM32 - http://wasm.ru/toollist.php

Ollydbg - ссылка для скачивания и работа с Ollydbg описана здесь: http://wasm.ru/article.php?article=ollydbg01

FAR - http://www.farmanager.com/download.php?l=ru

А я по-моему взял FAR здесь: http://www.piter.com/book.phtml?978594723757 (файлы к книге)

Как я уже писал - работа с Ollydbg описана здесь: http://wasm.ru/article.php?article=ollydbg01
Поэтому опишу только, как удобнее запускать эту программу.

Запуск Ollydbg.
Первый вариант запуска Ollydbg.
Создаём папку с батниками для этого:
- запускаем FAR
- разворачиваем FAR на весь экран, для этого нажимаем Alt+F9
- выбираем диск, для этого нажимаем Alt+F1 или Alt+F2
- выбираем директорию для создания папки с батниками
- создаём папку с батниками, а для этого нажимаем F7 и пишем имя папки, например: bats
- переходим в созданную папку
- создаём файл .bat, для этого нажимаем Shift+F4 и пишем название, например: odbg.bat
- в файле пишем путь к exe-файлу, у меня так:
start "" "C:\Program Files\Ollydbg\OLLYDBG.EXE"
Примечание. Если в открытом файле нажать Ctrl+F, то напечатается путь к текущему файлу.
- сохраняем, для этого нажимаем F2
- закрываем файл, нажимаем F10
- прописываем путь к папке bats, для этого: (для Windows 7) Пуск --> Панель управления --> Система --> Дополнительные параметры системы --> Переменные среды --> выбираем "Path" --> Изменить --> в поле "Значение переменной" дописываем путь к папке "bats", у меня так: F:\bats
Примечание. Пробелов после "точки с запятой" не должно быть!
- перезапускаем FAR

Теперь мы можем запустить Ollydbg, набрав в командной строке: odbg (в нижней части оболочки Far)

Результат запуска можно увидеть, нажав: Ctrl+O (вернуться обратно так же: Ctrl+O).

В запущенной Ollydbg выбираем в меню: File --> Open --> выбираем нужный exe-файл

Второй вариант запуска Ollydbg.
- для Windows 7: Пуск --> Панель управления --> Система --> Дополнительные параметры системы --> Переменные среды --> выбираем "Path" --> Изменить --> в поле "Значение переменной" дописываем путь к папке "Ollydbg", у меня так: C:\Program Files\OllyDbg
Примечание: пробелов перед "точкой с запятой" и после неё не должно быть!
- перезапускаем FAR

После выполнения настройки для второго варианта запуска мы можем запустить Ollydbg, находясь в директории с тем exe-файлом, который нужно отладить, набрав в командной строке оболочки FAR строку:
ollydbg filename

Нужно настроить оба способа запуска.

Сборка проекта с помощью программы ассемблера MASM32:
Создаём папку с батниками для этого (если папка уже есть, то пропускаем этапы создания папки, добавление Path и перезапуск FAR):
- запускаем FAR
- нажимаем Alt+F9, чтобы развернуть на весь экран
- нажимаем Alt+F1 или Alt+F2, чтобы выбрать диск
- выбираем директорию для создания папки с батниками
- создаём папку с батниками, а для этого нажимаем F7 и пишем имя папки, например: bats
- переходим в созданную папку
- нажимаем Shift+F4, чтобы создать файл и пишем название, например: amake.bat
- в файл копируем слудующее:
Цитата:
ml /c /coff "%1.asm"
link /SUBSYSTEM:CONSOLE "%1.obj"
- нажимаем F2, чтобы сохранить
- нажимаем F10, чтобы выйти
- для Windows 7: Пуск --> Панель управления --> Система --> Дополнительные параметры системы --> Переменные среды --> выбираем "Path" --> Изменить --> в поле "Значение переменной" дописываем путь к папке "bats", у меня так: F:\bats
Примечание: пробелов перед "точкой с запятой" и после неё не должно быть!
- перезапускаем FAR

Теперь мы можем создать exe-файл, имея написанную программу в файле "filename.asm". Набираем в командной строке оболочки FAR следующее:
Цитата:
amake filename
Результат сборки можно увидеть, нажав: Ctrl+O (вернуться обратно так же: Ctrl+O).

Теперь настало время рассмотреть первую демонстрационную программу.

Последний раз редактировалось 8Observer8; 14.09.2012 в 14:41.
8Observer8 вне форума Ответить с цитированием
Старый 14.09.2012, 14:27   #2
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию Простая командная строка.

Краткое описание:
Программа сохраняет адрес начала командной строки.

commline.asm
Код:
.386
.model  flat, stdcall
option  casemap:none

include    c:\masm32\include\windows.inc
include    c:\masm32\include\kernel32.inc
includelib c:\masm32\lib\kernel32.lib

.data?
commline dd ?

.code
start:

    invoke GetCommandLine

    mov commline, eax

    invoke  ExitProcess, 0
end start
8Observer8 вне форума Ответить с цитированием
Старый 14.09.2012, 14:31   #3
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

Предварительное содержание:

- Инструкция работы с инструментарием
- Простая командная строка
8Observer8 вне форума Ответить с цитированием
Старый 19.09.2012, 16:44   #4
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

я , скорее всего, догадываюсь, что данная тема несет некоторое знание и свет в массы.. но все-таки, не понимаю зачем создавать командную строку, или окно на асме, когда все это, на мой взгляд, гораздо приятнее сделать на c/c++, или другом языке высокого уровня. объясните, плиз, зачем это? в чем преиумущество?
я бы еще понял пограммирование на асме возведения в степень, к примеру, которое на пол-такта быстрее чем стандартная реализация, или чего-нибудь модное с использованием SSE или AVX. но "простая командная строка"? - не понимаю.
f.hump вне форума Ответить с цитированием
Старый 20.09.2012, 14:33   #5
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

пример 0:
функция поиска подстроки в строке (строки тут предполагаются C-style)

Код:
ALIGN 16
?SearchCStr@@YAPEADPEBD0@Z	PROC
; сохраняем регистры
	MOV r15, rdi   
	MOV r14, rsi

		MOV rdi, rcx
		MOV r13, rcx
		MOV rsi, rdx

		XOR rax, rax

; меряем длину строки
		XOR rcx, rcx		
		NOT rcx

		REPNZ SCASB
		
		MOV r10, rcx

; меряем длину подстроки
		XOR rcx, rcx
		NOT rcx

		MOV rdi, rsi

		REPNZ SCASB

		MOV r11, rcx
		ADD r11, 3
		NEG r11

		
		SUB rcx, r10
		MOV r10, rcx

		MOV rdi, r13
		

align 16
	sloop:
; ищем первый символ подстроки
		MOV al, [rsi]
		MOV rcx, r10
		REPNZ SCASB
		JNZ sexit
			MOV r10, rcx
			MOV rcx, r11

			AND rcx, rcx
			CMOVZ rax, rdi
			JZ sexit
align 16
			dsearch:
; проверям остальные символы подстроки
				MOV al, [rsi+rcx]
				CMP al, [rdi+rcx-1]
			LOOPZ dsearch

			CMOVZ rax, rdi
			JNZ sloop

		sexit:

		SUB rdi, 1
		SUB rax, 1

		XOR rdi, rax
		CMOVNZ rax, rcx	

; восставливаем регистры	
	MOV rsi, r14
	MOV rdi, r15

; результат в rax
	RET
?SearchCStr@@YAPEADPEBD0@Z	ENDP
я пишу для x64 винды, и использую компиляторы из SDK 7.1.

объявлена функция следующим образом:
Код:
extern char * SearchCStr(const char * source, const char * sblock);
если подстрока не найдена результат - 0, если найдена результат - указатель на то место где она найдена.

Последний раз редактировалось f.hump; 20.09.2012 в 16:46.
f.hump вне форума Ответить с цитированием
Старый 20.09.2012, 17:27   #6
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,322
По умолчанию

f.hump, спасибо за код! Я чуть позже продолжу здесь. Сейчас нужно закончить тему: http://www.programmersforum.ru/showp...7&postcount=40
8Observer8 вне форума Ответить с цитированием
Старый 24.09.2012, 14:18   #7
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

пример 1: функция копирования блока памяти.

Код:
ALIGN 16
MemoryCopy_SSE3	PROC
		
		SHR r8, 6

		JZ exit
			SUB r8, 2
			JE notouching
			JL notouching2
align 16			
			cpy64:
				MOV eax, [rdx+128]

				MOVDQA xmm2, [rdx]
				MOVDQA xmm3, [rdx+16]
				MOVDQA xmm4, [rdx+32]
				MOVDQA xmm5, [rdx+48]

				MOVNTDQ [rcx], xmm2
				MOVNTDQ [rcx+16], xmm3
				MOVNTDQ [rcx+32], xmm4
				MOVNTDQ [rcx+48], xmm5

				CLFLUSH [rdx]
				ADD rcx, 64
				ADD rdx, 64

				SUB r8, 1
			JNZ cpy64		
		notouching:
		
			MOVDQA xmm2, [rdx]
			MOVDQA xmm3, [rdx+16]
			MOVDQA xmm4, [rdx+32]
			MOVDQA xmm5, [rdx+48]

			MOVNTDQ [rcx], xmm2
			MOVNTDQ [rcx+16], xmm3
			MOVNTDQ [rcx+32], xmm4
			MOVNTDQ [rcx+48], xmm5

			CLFLUSH [rdx]
			ADD rcx, 64
			ADD rdx, 64
		notouching2:
			MOVDQA xmm2, [rdx]
			MOVDQA xmm3, [rdx+16]
			MOVDQA xmm4, [rdx+32]
			MOVDQA xmm5, [rdx+48]

			MOVNTDQ [rcx], xmm2
			MOVNTDQ [rcx+16], xmm3
			MOVNTDQ [rcx+32], xmm4
			MOVNTDQ [rcx+48], xmm5

			CLFLUSH [rdx]


			
		exit:
			
	RET
MemoryCopy_SSE3 ENDP
Код:
extern "C" void MemoryCopy_SSE3(void * const destination, const void * source, __int64 byte_count);
примечание: destination и source должны быть выравнены по 16 байтной границе, byte_count - кратен 64.
f.hump вне форума Ответить с цитированием
Старый 24.09.2012, 14:46   #8
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

небольшой комментарий про Windows x64.

принимая во внимание, что в 64-х битном режиме есть 16 64-х битных регистров общего назначения, то в этом режиме используется только __fastcall. Это значит, что первые четыре аргумента функции передаются через регистры (rcx, rdx, r8, r9), а остальные по стеку. Если среди первых четырех аргументов есть синглы и даблы, то они передаются через xmm0, xmm1, xmm2, xmm3.

например, если есть функция func(single, my_struct &, int, double), то будут задействованны регистры xmm0, rdx, r8 и xmm3.

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

в принципе, если функция использует rbx, rbp, rdi, rsi, rsp, r12-r15, xmm6-xmm15, то она должна их сохранять/восстанавливать. я пока, по старинке, делаю это только для rbx, rbp, rdi, rsi, rsp, до первого бага, что называется.

Последний раз редактировалось f.hump; 24.09.2012 в 14:55.
f.hump вне форума Ответить с цитированием
Старый 25.09.2012, 15:11   #9
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

про использование VS C++ 2010 Express вместе с Windows SDK для х64 асма.

Как многие наверняка знают, компиляторы Майкрософта не поддерживают inline assemby для 64-х битного кода. Почему так, я понятия не имею, но думаю, что так компиляторы им писать проще.
Так вот, если у кого возникает потребность разнообразить свой C/C++ код ассеблером, для удовлетворения некоторых садо-мазо желаний, либо по непонятным причинам, с использованием VS C++ 2010 Express, то поступить нужно следующим образом:

1. В солюшн иксплорере кликнуть правой кнопкой мыши на проекте, который хочется улучшить, и выбрать Build Customizations.. В появившемся окне поставить галочку напротив masm. Данная операция упростит конфигурацию .asm файлов, в том плане, что студия будет их когфигурировать автоматически.

2. В солюшн иксплорере кликнуть правой кнопкой мыши на проекте, который хочется улучшить, и выбрать Свойства. В появившемся окне, Configuration Properties->General->Platform Toolset, выбрать Windows X.X SDK. Связанно это с тем, что VS C++ Express идет без компиляторов для x64.

3. В солюшн иксплорере кликнуть правой кнопкой мыши на проекте, который хочется улучшить, и выбрать Add->New Item... Выбрать Code и вписать имя файла вместе с расширением (.asm).

Все готово для улучшения проекта. Вот пример пустого сорс файла:
Код:
.CODE

END

Последний раз редактировалось f.hump; 25.09.2012 в 15:42. Причина: [B]Properties[/B]
f.hump вне форума Ответить с цитированием
Старый 25.09.2012, 19:12   #10
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

еще пару слов про Windows x64.

Как уже было отмечено аргументы функции передаются через регистры и стек. Первые 4 через регистры слева направо, остальные через стек справа налево. Тот кто вызывает функцию резервирует стек под параметры и тут нужно помнить про то, что называется shadow space или home space. В х64 действеут соглашение согласно которому любой функции гарантируется 32 байта стека для того, чтобы дампить параметры переданные через регистры (или других целей). (Как я понимаю, сделано это для поддержки vararg.) Это означает, что тот кто вызывает функцию отвечает за выделение и освобождение этих 32-х байт, потому что вызываемой функции разрешено считать, что у нее есть эти 32 байта без каких-либо проверок.

Код:
...
MOV rax, 15
MOV rdx, [param_count_N]
LEA r13, [rdx*8 + rax]
NOT rax
AND r13, rax

SUB rsp, r13

MOV rax, [param_N]
MOV [rsp+(N-1)*8], rax
MOV rax, [param_(N-1)]
MOV [rsp+(N-2)*8], rax
....

MOV rax, [param_5]
MOV [rsp+32], rax

MOV r9, [param_4]
MOV r8, [param_3]
MOV rdx, [param_2]
MOV rcx, [param_1]

CALL some_function

ADD rsp, r13

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

Последний раз редактировалось f.hump; 26.09.2012 в 00:02.
f.hump вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Составить на языке ассемблера IBM PC подпрорамму вычисления Airat1790 Помощь студентам 0 18.04.2012 13:39
Нужны шаблоны(примеры программ) по Паскалю Сержuk Помощь студентам 1 10.03.2011 14:48
На языке ассемблера IBM PC создать подпрограммы: Gertryda Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 09.01.2011 23:13