Пирогов Владислав Юрьевич

О программировании, ИТ и обо всем по немногу

Previous Entry Share Next Entry
64-битовое программирование в Windows на ассемблере
pirogov_vju
Первой вопрос, который, я хочу рассмотреть и  который, мне кажется, сейчас очень важным, это 64-битовое программирование.  Естественно речь пойдет об ассемблере. В качестве такового возьмем  fasm. Во-первых, поддерживает 64-битовое программирование, во-вторых, этот ассемблер является кроссплатформенным. Для того, чтобы начать писать 64-битовые программы достаточно 1. Узнать структуру программы; 2. Использовать правильное соглашение вызова системных и вообще функций.
Программирование в Windows.
В 64-битовых Windows принята следующая конвенция вызова функций (в том числе вызов функций API).
1. Первые четыре параметра передаются в функцию через регистры: rcx, rdx, r8, r9. Остальные параметры (если они есть) передаются через стек.
2. Перед вызовом функции резервируется область в стеке, на случай, если вызываемая функция "захочет" временно сохранить параметры в стеке. Таким образом, параметры, которые передаются через стек, помещаются туда после резервируемой области.
3. При передаче параметров, размер которых меньше 64 бит, передаются как 64-битовые параметры. При этом следует обнулить старшие биты. Параметры, большие 64-бит передаются по ссылке.
4. Данные возвращаются через регистр rax. Если возвращаемое значение имеет размер больший 64 бит, то данное передается через область памяти, адрес которой передается в первом параметре. Для возвращения может также использоваться регистр xmm0.
5. Все регистры при вызове функций сохраняются за исключением rax, rcx, rdx, r8, r9, r10, r11, сохранность которых не гарантируется.
6. Граница стека должна быть выровнена по адресу кратному 16.
Рассмотрим в общих чертах схему вызова функции API с пятью параметрами.

...
sub rsp,40 ; резервируем стек
mov qword ptr [rsp+32],par5
mov r9,par4
mov r8,par3,
mov rdx,par2
mov rcx,par1
call f_api64
...
add rsp,40 ;восстанавливаем стек
...


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

sub rsp,40 ; резервируем стек
mov r9,par4
mov r8,par3,
mov rdx,par2
mov rcx,par1
call f_api64
...
add rsp,40 ;восстанавливаем стек


Рассмотрим следующую программу

format PE64 GUI
entry start
section '.text' code readable executable
start:
sub rsp,8*5
mov r9,0
lea r8,[_caption]
lea rdx,[_message]
mov rcx,0
call [MessageBoxA]
add rsp,40
sub rsp,16
mov ecx,eax
call [ExitProcess]
section '.data' data readable writeable
_caption db 'Win64 assembly program',0
_message db 'Hello World!',0
section '.idata' import data readable writeable
dd 0,0,0,RVA kernel_name,RVA kernel_table
dd 0,0,0,RVA user_name,RVA user_table
dd 0,0,0,0,0
kernel_table:
ExitProcess dq RVA _ExitProcess
dq 0
user_table:
MessageBoxA dq RVA _MessageBoxA
dq 0
kernel_name db 'KERNEL32.DLL',0
user_name db 'USER32.DLL',0
_ExitProcess dw 0
db 'ExitProcess',0
_MessageBoxA dw 0
db 'MessageBoxA',0


Если имя программы prog.asm, то компилируется она просто командой
fasm prog.asm


Как видите, в Windows все просто.

Пирогов В.Ю, (
http://asm.shadrinsk.net)


Linux 64, продолжение следует...

  • 1

site 9943

(Anonymous)
[url=http://commentjob.ru/#kdqob]click[/url] - here (http://commentjob.ru/#tokum) , http://commentjob.ru/#ngcca site

Андрей

(Anonymous)
Добрый день, хотелось бы прояснить для себя некоторые моменты. 1. В примере передачи параметров mov cdx,par1 опечатка? RCX должно быть вроде же как. 2. lea r8,[_caption] синтаксис FASM позволяет использовать команду MOV для передачи адреса начала строки при помощи квадратных скобок Пример MOV R8,_caption однако Вы этого избегаете. Это дело "вкуса" или есть какие то более веские причины? Есть ещё куча дилетантских вопросов, но не будучи уверенным что у вас найдётся на них время ограничусь пока что этими двумя.

Добрый день, Андрей!
Спасибо, что написали.
1).
Я здесь ошибся и должно стоять mov rcx,par1.
Я уже это исправил.
2). Запись mov rcx,par1 - это так сказать общая форма записи, показывающая, что в регистр rcx помещается некоторое значение. В реальной программе это может и просто число: mov rcx, 10; и адрес: mov rcx, var1 (адрес переменной в регистр rcx, можно, конечно и так lea rcx,[var1], дело вкуса); и содержимое ячейки mov rcx,[var1].

Вот и все, собственно. Пишите, с удовольствием отвечу.

http://asm.shadrinsk.net



Edited at 2013-07-31 10:50 am (UTC)

Re: Андрей

(Anonymous)
Вопрос 1.
Не очень понял, с четырьмя параметрами и в примере с пятью параметрами нужно резервировать по сорок байт. Это истекает из "Граница стека должна быть выровнена по адресу кратному 16"?
Тогда получается при вызове функции с одним параметром необходимо делать sub rsp,40
А если функция имеет шесть параметров, то с учётом того что нужно сохранить адрес возврата придётся делать так sub rsp,48+40
Правильно я понял?

Вопрос 2. Как обстоят дела с книгой по 64 битному программированию?

Всё понятно, кроме одного. Зачем резервировать в стеке место для всех параметров функции, если четыре из них через регистры? Вот такой код на masm вполне себе работает.

includelib \masm32\lib64\user32.lib
includelib \masm32\lib64\kernel32.lib

extern MessageBoxA:proc
extern ExitProcess:proc

.code

start proc
mov rbp,rsp
and rsp,-16

xor r8,r8
xor r9,r9
xor rdx,rdx
xor rcx,rcx
call MessageBoxA

mov rsp,rbp
ret
start endp
end


Всё понятно, кроме одного. Зачем резервировать в стеке место для всех параметров функции, если четыре из них передаются через регистры? Вот такой код на masm вполне себе работает.

includelib \masm32\lib64\user32.lib
includelib \masm32\lib64\kernel32.lib

extern MessageBoxA:proc
extern ExitProcess:proc

.code

start proc
mov rbp,rsp
and rsp,-16

xor r8,r8
xor r9,r9
xor rdx,rdx
xor rcx,rcx
call MessageBoxA

mov rsp,rbp
ret
start endp
end


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

http://asm.shadrinsk.net

Edited at 2013-07-31 10:49 am (UTC)

Богдан

(Anonymous)
Как то непропорционально развит этот процессор
Если они не могли сделать 64-разрядную полноценную реализацию то зачем вообще за нее взялись
Да и не реализовали они ее, страницы памяти будут слишком велики
Сейчас хорошей реализацией будет скажем добавление 1-2 битов к уже существующей 32 битовой адресации
Сделали бы 34-36 бит
И страницы памяти на процессоре были бы не такими большими

Тогда и регистры можна было бы применять в полную силу
А 16-64 Гиг той же оперативки вполне себе ничего
Больше никто и не ставит

Вообще говоря основные когда будет сделана доступная людям память с произвольным доступом и в необходимом обьеме
Ну вообще говоря быстрая память с произвольным доступом+процессор очень RISC
Тогда все программы превратятся в прошивку
Для обработки видео будут применятся многоядерные процессоры
Ну а прошивка Гетсов и национальностей не различает
так что полетит эта куча
"малосовместимого железа на ближайшую свалку"

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




Re: Богдан

(Anonymous)
Смысл делать 34-36 бита если уже на сегодняшний день полно файлов едва ли укладывающихся в эту "размерность" блюреи всякие и прочие авишки с ашди. Опять переходить на постраничную адресацию? Так только от неё отмазались. И потом для передачи полного адреса всё равно минимум будет задействован байт.

Богдан

(Anonymous)
Что я забыл добавить что систему команд процессора уже сейчас можна представить в виде "статической(неизменяемой) памяти"
с произвольным доступом, в виде резистивной памяти
Даже без диодов, т.е. ее можна сделать и из металлов
Так же как и любую логическую функцию можна представить в виде таблицы

Очень простой вариант такой памяти это резистивная память
Что хорошего в "статической памяти с произвольным доступом"?
Можна очень сильно упростить архитектуру процессора
именно по кремниевым технологиям, деталек поставить
не 1 000 000 000 , а скажем 300-500 деталек

Тут же упадет потребляемая мощность того же процессора
Ведь никаких вычислений фактически не производится
Только доступ к "статической памяти"
И получение данных из таблиц

Это можна было сделать уже очень давно и процессор можна было бы охлаждать не здоровенным вентилятором, а небольшим таким себе и компютер потребял бы не 300-500 Ватт, а скажем
ват 10-15
И так реализовать систему команд можна не только в самом процессоре а во всем компютере

И довести потребление энергии компютером до уровня мобильного телефона
Это реально и осуществимо, а они туда железа пихают и пихают
Оно греется , а они этажи строят
Бред какой та



Jfekfjw wkj 875thnjt6u t5y45y5t45y6

(Anonymous)
Xighefjeo orj wokwp dkow pwk wodj d hfdgfhgf 4756 5uhtyjur urt45

Элит досуг

(Anonymous)
Приветствую пользователей ресурса! Представляем досуг с элитными девушками все подробности можно узнать по мылу dosug-elitei@mail.ru

Free accomplishment of written work

(Anonymous)
Hello friends!
I am an official representative of private company which deals with all kinds of written work (essay, coursework, dissertation, presentation, report, etc) in short time.
We are ready to offer a free accomplishment of written work hoping for further cooperation and honest feedback about our service.
Send your work topics to our email: discount@edu-paper.com. This offer has limited quantities!!!

  • 1
?

Log in

No account? Create an account