Сейчас на форуме: bartolomeo, -Sanchez- (+3 невидимых)

 eXeL@B —› Вопросы новичков —› Как в стек втолкнуть 1 байт?
Посл.ответ Сообщение

Ранг: 0.6 (гость)
Активность: 0=0
Статус: Участник

Создано: 08 февраля 2006 13:36
· Личное сообщение · #1

Как в стек втолкнуть 1 байт?
Например есть
var1 db 5

Masm ругается и на такое:

push var1,

и на такое:
mov al, var1
push al

Я так понял, что в стек можно толкать только Word.
Как можно втолкнуть байт?

Извните если не по теме, просто не знаю где сппросить, Wasm.ru не работает



Ранг: 5.7 (гость)
Активность: 0=0
Статус: Участник

Создано: 08 февраля 2006 14:19
· Личное сообщение · #2

В любом учебнике по ассемблеру ...при записи в стек 8-битных значений для них все равно выделяется слово или двойное слово (в зависимости от use16 или use32)...
push var1 - попытка записать в стек оффсет переменной var1, а не самой ее.

mov al, var1
push al


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




Ранг: 605.2 (!), 341thx
Активность: 0.470.25
Статус: Модератор
Research & Development

Создано: 08 февраля 2006 15:17
· Личное сообщение · #3

.data
var1 dw 5

.code
lea eax, var1
push word ptr [eax]

-----
EnJoy!




Ранг: 5.7 (гость)
Активность: 0=0
Статус: Участник

Создано: 09 февраля 2006 09:50
· Личное сообщение · #4

О-о-псс, пора имне повторять изученное по ассемблеру, потому что мне кажется, что push word ptr [eax] затолкнет в стек только первые 4 байта из переменной var1...



Ранг: 0.6 (гость)
Активность: 0=0
Статус: Участник

Создано: 09 февраля 2006 13:58
· Личное сообщение · #5

Jupiter
lea eax, var1 ; загружаем в Eax эффективный адрес переменной var1
push word ptr [eax]; push в стэк eax, меняя атрибут типа (только не понял почему не Byte ptr[eax], ведь у нас и так Var1 типа Word)

а почему нельзя push offset var1?

Но проблема немного не в том.

____________________________________________________
var1 | var2 | var3| var4| var5 | var6 | var7 | var8
____________________________________________________
db | db | dw | dw | dw | dw | db | db


Нужно через стек поменять

____________________________________________________
var7 | var1 | var4| var6| var3 | var5 | var8 | var2
____________________________________________________


Я думаю примерно так:
push offset var1
push offset var2
push offset var3
push offset var4
push offset var5
push offset var6
push offset var7
push offset var8

pop var7
pop var1
pop var4
pop var6
pop var3
pop var5
pop var8
pop var2

Или нет?



Ранг: 210.5 (наставник), 2thx
Активность: 0.140
Статус: Участник

Создано: 10 февраля 2006 00:35
· Личное сообщение · #6

Spitfire пишет:
Как в стек втолкнуть 1 байт?
Например есть
var1 db 5

Masm ругается и на такое:

push var1,

и на такое:
mov al, var1
push al

Я так понял, что в стек можно толкать только Word.


Можешь делать так (вместа push al): (синтакс: фасм)

dec esp
mov byte [esp],al


Потом вместа pop al:

mov al, byte [esp]
inc esp


Но пользы от этого я не вижу. После "псевдо" push al не вздумай делать нормальный pop chto_to, пока не сделаешь "псевдо" pop al, думаю ясно почему...



Ранг: 495.3 (мудрец)
Активность: 0.30
Статус: Участник

Создано: 10 февраля 2006 09:06 · Поправил: Bitfry
· Личное сообщение · #7

Всех бы нах забанил

al_begin пишет:
push var1 - попытка записать в стек оффсет переменной var1, а не самой ее.

Ты видишь здесь директиву offset?
Синтаксис MASM'a предполагает:
"[var1]" то же самое что "var1"

Такая нестрогость путает всех новичков. Я бы посоветовал всегда брать в скобки, тем более что "эталонный" синтаксис другого варианта и не даёт. Если нужен указатель – "var1", если значение – "[var1]".

al_begin пишет:
В любом учебнике по ассемблеру ...при записи в стек 8-битных значений для них все равно выделяется слово или двойное слово (в зависимости от use16 или use32)...

Только нужно сказать, речь идёт про компилятор MASM'a а не про Ассемблер.
Не парте себе мозги, взгляните на возможные инструкции процессора.

arnix пишет:
Можешь делать так (вместа push al): (синтакс: фасм)
dec esp
mov byte [esp],al
Потом вместа pop al:
mov al, byte [esp]
inc esp
Но пользы от этого я не вижу. После "псевдо" push al не вздумай делать нормальный pop chto_to, пока не сделаешь "псевдо" pop al, думаю ясно почему...

Бред. Причём тут стек?

Spitfire пишет:
а почему нельзя push offset var1?

Можно, но ты получишь в стеке указатель на переменную, а не её значение.

Так теперь к сути.

Стек это всего лишь область памяти на вершину которой указывает ESP/SP (32bit/16bit)
Работу со стеком поддерживают некоторые команд процессора.
А они предполагают несколько правил таких как...

1. Стек растёт от старшего адреса к младшему.
2. Эти команды могут обработать только 16 бит или 32 бита.

Кроме того, операционная система тоже требует своих правил при работе со стеком.
В Windows лучше не делать dec ESP. Процессор это позволяет, но при вызове API-функции, которая уходит в ring0 (а это большинство функций), будет бяка. Таким образом, самое разумное это учитывать правило:
в Win32 стек должен быть кратен 32.

Про возможности процессора.

В 32 битном режиме адресации и операндов можно сделать так:
50h push EAX
66:50h push AX


Если режим 16 битный, то будет наоборот:

50h push AX
66:50h push EAX


Если перед опкодом стоит байт 66h, то эта команда использует префикс размера операнда.
В форточках можно дважды запихнуть в стек 16-битное значение, и всё будет как надо, главное чтоб было кратно 32.

Ещё раз: push, pop, call, ret и т.д. могут работать только с word или dword.
В Win32 по умолчанию это будет dword.

Вывод.
Если нужно поменять значения переменных в форточной проге, делаем это так:
(смотри атач, musor из архива удалить, файлы меньше 20 кило не цепляются)

Хотя из твоих расстановок не очень понятно, что ты собственно хочешь =).

ЗЫ Всем читать(!):
bitfry.narod.ru

-----
Всем привет, я вернулся




Ранг: 495.3 (мудрец)
Активность: 0.30
Статус: Участник

Создано: 10 февраля 2006 09:42
· Личное сообщение · #8

Пример:

7ea2_stack_example.rar.zip

-----
Всем привет, я вернулся




Ранг: 0.6 (гость)
Активность: 0=0
Статус: Участник

Создано: 10 февраля 2006 13:10
· Личное сообщение · #9

Всем большое спасибо!
И последний вопрос:
Почему не работае movzx ax,byte ptr [var1]? (просто под Dos надо написать)
Error A2105: Expected: instruction or directive

Ведь в качестве первого операнда Movzx может использоваться 16 или 32 разрядный регистр?
И еще
Bitfry пишет:
Если режим 16 битный, то будет наоборот:

50h push AX
66:50h push EAX

Это как? В 16-битном режиме вроде нет eax



Ранг: 210.5 (наставник), 2thx
Активность: 0.140
Статус: Участник

Создано: 10 февраля 2006 13:45
· Личное сообщение · #10

Bitfry пишет:

arnix пишет:
Можешь делать так (вместа push al): (синтакс: фасм)
dec esp
mov byte [esp],al
Потом вместа pop al:
mov al, byte [esp]
inc esp
Но пользы от этого я не вижу. После "псевдо" push al не вздумай делать нормальный pop chto_to, пока не сделаешь "псевдо" pop al, думаю ясно почему...

Бред. Причём тут стек?


Как это причем тут стэк? Или ты скажешь что не знаешь для чего предназначен регистр ESP ??
push eax (втолкнули в стэк значение регистра EAX)

Тоже самое можно сделать так:

sub esp,4
mov dword [esp], eax

Или я не прав по-твоему?



Ранг: 495.3 (мудрец)
Активность: 0.30
Статус: Участник

Создано: 10 февраля 2006 18:22 · Поправил: Bitfry
· Личное сообщение · #11

arnix пишет:
Как это причем тут стэк? Или ты скажешь что не знаешь для чего предназначен регистр ESP ??

Давай думать вместе.
Вообще благодаря чего существует стек?
Ответ: исключительно благодаря нескольких команд процессора (push, pushad, pop, popad, call, ret... Может чего забыл).
Ведь не было бы этих команд и стек "перестал бы существовать".
В свою очередь эти команды для выполнения используют сегментный регистр стека (SS) и регистр указателя вершины стека ESP/SP.
Согласен?
Но с другой стороны, ESP – это один из регистров общего назначения (РОН).
Так вот каждый РОН имеет двойной смысл. Их можно использовать по прямому назначению (аккумулятор, база, счётчик... индекс), а можно как "переменные" для собственных нужд (хранить там результаты вычислений или указатели).

Моё представление такое: твой первый пример это использование регистра ESP как указатель на область памяти и всё.
(А вот последний пример можно рассматривать двояко )
Ты ведь не можешь использовать команды для работы со стеком, чтоб достать один байт?
Ещё раз повторю, стека нет без команд процессора для работы с ним.
Можно творить всё, что душе угодно с памятью и РОН, но если мы не придерживаемся правил работы со стеком, это просто область памяти и просто регистр общего назначения ESP.
Конечно, это не так важно, но лучше сразу в голове навести порядок, дальше проще будет.


Spitfire пишет:
И последний вопрос:
Почему не работае movzx ax,byte ptr [var1]? (просто под Dos надо написать)
Error A2105: Expected: instruction or directive

Ведь в качестве первого операнда Movzx может использоваться 16 или 32 разрядный регистр?

Правильно, поэтому должно работать.
Возможно, ты забыл "сказать", что мы пишем прогу для процессора 80386 и выше.
Или нужно на двойке показывать?
Деректива MASM ".386"... Ещё раз повторяю – читай мои статьи!

А вот "movzx ax, word ptr [var1]" и недолжно работать .
Короче, пример для DOS:
19cb_dsex.asm.zip

Spitfire пишет:
И еще...
50h push AX
66:50h push EAX
Это как? В 16-битном режиме вроде нет eax

Кто тебе такое сказал?
На 16-бинтой двойке – да, а на тройке уже есть E-регистры, так что мешает их использовать?

-----
Всем привет, я вернулся




Ранг: 210.5 (наставник), 2thx
Активность: 0.140
Статус: Участник

Создано: 10 февраля 2006 23:45 · Поправил: arnix
· Личное сообщение · #12

Bitfry пишет:
Давай думать вместе.


Давай

Bitfry пишет:
Моё представление такое: твой первый пример это использование регистра ESP как указатель на область памяти и всё.


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

Bitfry пишет:
Ты ведь не можешь использовать команды для работы со стеком, чтоб достать один байт?


Если ты имеешь ввиду push/pop, то да, не могу

Bitfry пишет:
Ещё раз повторю, стека нет без команд процессора для работы с ним.


Вот, я не согласен Я могу написать программу на асме, которая не испоьзует команды push, pop, call, ret но прекрасно работает (вызывает системные функции и.т.д.). Конечно это будет не удобно и вместо одной команды я должен буду писАть несколько, но что важно - работа со стэком возможна без этих команд, Тойсть они (эти команды) просто удобное средство для работы с областью памяти, на которую указывает регистр ESP (хотя согласен, стэк можно так называть с некоторами оговорками). Меняем значение ESP, например так, mov esp, 400100, и можем испоьзоваьт эти "удобные команды для работы со стэком" для работы с памятью в области 400100:

Вместа: (фасм)
mov dword [400100],eax
mov eax, dword [400200]

Так:
mov ebp,esp
mov esp,400100+4 ; нужно иметь право тут писАть, иначе - exception
push eax
mov esp,400200
pop eax
mov esp,ebp

Конечно наверно нет смысла так "извращаться" в реальной программе (хотя может и иметь, если протектор пишешь )

Bitfry пишет:
Можно творить всё, что душе угодно с памятью и РОН, но если мы не придерживаемся правил работы со стеком, это просто область памяти и просто регистр общего назначения ESP.


Правила? Покажи где они написаны



Ранг: 495.3 (мудрец)
Активность: 0.30
Статус: Участник

Создано: 11 февраля 2006 08:51
· Личное сообщение · #13

Дальнейший спор не имеет смысла. Думаю ты всё давно сам понял. Да, я согласен, всё можно рассматривать с разных сторон, всё двояко (минимум =).
arnix пишет:
Я могу написать программу на асме, которая не испоьзует команды push, pop, call, ret но прекрасно работает (вызывает системные функции и.т.д.)

...
arnix пишет:
Правила? Покажи где они написаны

Напиши такую программу, не используя те правила (кратность 32, рост от старшего адреса к младшему...).

Если бы совсем не было команд работы со стеком, никакого стека не было бы. Даже уговор программистов использовать область памяти для передачи параметров оказался бы наверняка другим, и это был бы не стек.
Ну, отвлеките чуть-чуть голову от практики, подумайте абстрактно!

-----
Всем привет, я вернулся




Ранг: 5.7 (гость)
Активность: 0=0
Статус: Участник

Создано: 22 февраля 2006 18:03
· Личное сообщение · #14

...они сошлися: лёд и пламень...

Выдержки из мануалов Intel (25366517.pdf, 25366617.pdf...)

Words, doublewords, and quadwords do not need to be aligned in memory on natural boundaries. The natural boundaries for words, double words, and quadwords are even-numbered addresses, addresses evenly divisible by four, and addresses evenly divisible by eight, respectively. However, to improve the performance of programs, data structures (especially stacks) should be aligned on natural boundaries whenever possible. The reason for this is that the processor requires two memory accesses to make an unaligned memory access; aligned accesses require only one memory access. A word or doubleword operand that crosses a 4-byte boundary or a quadword operand that crosses an 8-byte boundary is considered unaligned and requires two
separate memory bus cycles for access.

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

A program or operating system/executive can set up many stacks. For example, in multitasking systems, each task can be given its own stack. The number of stacks in a system is limited by the maximum number of segments and the available physical memory.
When a system sets up many stacks, only one stack—the current stack—is available at a time. The current stack is the one contained in the segment referenced by the SS register.

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

To set a stack and establish it as the current stack, the program or operating system/executive
must do the following:
1. Establish a stack segment.
2. Load the segment selector for the stack segment into the SS register using a MOV, POP, or
LSS instruction.
3. Load the stack pointer for the stack into the ESP register using a MOV, POP, or LSS
instruction. The LSS instruction can be used to load the SS and ESP registers in one
operation.

Чтобы установить стек и установить его как текущий стек, программа или операционная система / исполнитель /должны делать следующее:
1. Установить сегмент стека.
2. Загрузить селектор сегмента в регистр SS, используя MOV, POP, или команду LSS.
3. Загрузить указатель стека в регистр ESP, используя MOV, POP или команду LSS. Команда LSS может использоваться, чтобы загрузить SS и регистр ESP за одну операцию.

The processor does not check stack pointer alignment. It is the responsibility of the programs...
Процессор не проверяет выравнивание указателя стека. Это - ответственность программ...

перевод мой так, что за ошибки не пинайте.

Выходит, все что сказал arnix, неопровержимо...

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

PS. простите за флейм, настроение праздничное...



Ранг: 495.3 (мудрец)
Активность: 0.30
Статус: Участник

Создано: 23 февраля 2006 07:19
· Личное сообщение · #15

al_begin пишет:
Выходит, все что сказал arnix, неопровержимо...

Пожалуй, я почти соглашусь.

al_begin пишет:
Но я соглашусь с Bitfry, потому что он модератор

Плюсик автору в уме

al_begin пишет:
а заодно всех призываю пожаловаться на Солодовникова в Intel, за то что он, гад, использует стек не по правилам, мало того, что не выравнивает, но еще и выполняет в нем код и даже модифицирует его


Хм... Видимо всё-таки я не ясно выразил своё мнение.
ИМХО стек и правила его использования неразделимы.
Если мы изгиляемся над областью памяти под ESP, то это уже не работа со стеком. Тут вопрос динамики восприятия. В один момент это данные, в другой – код, с одной точки зрения это стек, с другой – переменная.
Мне кажется, если в голове представлять, что всё творящееся под ESP – это только работа со стеком, будет слишком сложно переваривать происходящее в запротекченых участках.

-----
Всем привет, я вернулся




Ранг: 5.7 (гость)
Активность: 0=0
Статус: Участник

Создано: 26 февраля 2006 12:08
· Личное сообщение · #16

Bitfry пишет:
...будет слишком сложно переваривать происходящее...

А никто и не говорил, что в сказку попадем...

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

Bitfry пишет:
...Вообще благодаря чего существует стек?
Ответ: исключительно благодаря нескольких команд процессора (push, pushad, pop, popad, call, ret... Может чего забыл).
Ведь не было бы этих команд и стек "перестал бы существовать"...
Согласен?


НЕТ!

Здесь классическая подмена курицы и яйца:

Именно благодаря идее СТЕКА, родившейся в умах программистов-теоретиков и появились вышеназванные команды процессора, реализованные инженерами, но никак не наоборот. И появились с целью облегчить написание программ (ну и уменьшить затраты времени на их выполнение), использующих методики СТЕКА.
Причем, если вспомнить историю, СТЕК использовался, в основном как временное хранилище регистров и адресов возврата из подпрограмм, и уже затем стал использоваться как область передачи локальных переменных для т.н. "высокоуровневых языков программирования". В качестве доказательства: о чем говорит введение в состав набора инструкций процессоров x86 команд ENTER и LEAVE, SYSENTER и SYSEXIT, а в 64-битных еще и SYSCALL и SYSRET. О том, что именно инженеры идут на поводу у програмистов и добавляют новые команды по разработанным последними методикам программирования. Вы же предлагаете пойти на поводу у инженеров, используя "правила", навязанные ими на данном технологическом этапе. ИМХО на этом развитие может остановится и мы получим "хороших и правильных программистов", которые будут использовать так горячо любимый многими китайскими программистами в составе команды Microsoft метод "Copy - Paste", благо оперативная память сейчас дешевеет...
ИМХО только нетривиально мыслящий реверсер может добиться результатов в крэкинге...

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



Ранг: 495.3 (мудрец)
Активность: 0.30
Статус: Участник

Создано: 02 марта 2006 09:23 · Поправил: Bitfry
· Личное сообщение · #17

al_begin
Мысли здоровые и я полностью согласен. Убедил.

al_begin пишет:
поэтому приношу извинения за невольно нанесенные обиды и во избежание дальнейшего флейма предлагаю топик закрыть

Да ну брось ты! Я здесь вообще вот из-за таких тем и обитаю, а их, кстати, не так уж много.

arnix
Извини, беру свои слова обратно, ты прав: можно воспринимать твой первый пример как работу со стеком, если уточнить, что это широкое практическое понимание стека.

Итак, делаю выводы.
1. Стек родился в умах теоретиков как промежуточное хранилище изначально неопределённого количества значений.
2. Практики сформулировали основное правило "первым вошел – последним вышел".
3. Инженеры Intel "заковали" стек регистрами SS:ESP и оптимизацией команд (для собственных нужд).
4. Программисты из MicroSoft (для собственных нужд) довели работу со стеком до того, о чём я писал выше (32 бита иначе – кирдык).

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

-----
Всем привет, я вернулся




Ранг: 79.6 (постоянный), 2thx
Активность: 0.080
Статус: Участник
алХимик

Создано: 02 марта 2006 10:54
· Личное сообщение · #18

Bitfry

Ты меня пугаешь... Свои ложные мысли выдаешь за неприложную истину, и еще на других товарищей наезжаешь, которые верные ответы дают. Если ты чего-то не знаешь, это не значит, что этого не сущесвует. Регистры ESP и EBP всегда использовались для произвольно (в широком смысле этого слова) доступа с стеку, причем не потому, что так придумали древние хэкеры, а потому что это заложено в архитектуре.

Bitfry пишет:
В Win32 по умолчанию это будет dword.


Причем тут Виндовз? Какой укажешь такой и будет ассемблировать, это зависит от настроек асемблера (use16 или use32). Правда смысла в 16-битном коде в работе с Виндовз нет, как и в другой аналогичной ОСи, но это другой разговор.

ЗЫ может последняя фраза немного кривая, но думаю смысл понятен.

-----
Все говорят что мы вместе. Но не многие знают в каком.




Ранг: 495.3 (мудрец)
Активность: 0.30
Статус: Участник

Создано: 03 марта 2006 06:43
· Личное сообщение · #19

SeDoYHg пишет:
Ты меня пугаешь...

Не бойся, я просто учусь чуть медленней чем думал ... И потом я же признал свою ошибку.

SeDoYHg пишет:
может последняя фраза немного кривая, но думаю смысл понятен.

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

-----
Всем привет, я вернулся




Ранг: 79.6 (постоянный), 2thx
Активность: 0.080
Статус: Участник
алХимик

Создано: 03 марта 2006 08:18
· Личное сообщение · #20

Bitfry пишет:
Не бойся, я просто учусь чуть медленней чем думал


Это свойственно людям за 20 8), я такой же пень =)). Главное не уподабляться товарищу Крысу, нахватавшись по верхам, писать книги.

Bitfry пишет:
хочется написать как можно доходчивей

Я бы сказал, ты стараешься делать обощения - это тебя и подводит.

ЗЫ

-----
Все говорят что мы вместе. Но не многие знают в каком.



 eXeL@B —› Вопросы новичков —› Как в стек втолкнуть 1 байт?
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати