Что произойдет, если я переместу определенный как размер слова размер байта в 32-битный регистр, как если бы он был определен как dword? - PullRequest
1 голос
/ 14 марта 2019

Вот код:

;NASM

section .data
a dw 0xDEAD

section .text 
...
mov eax, dword [a + 1]
; eax now equals 0xDE
...

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

Ответы [ 2 ]

2 голосов
/ 15 марта 2019
a dw 0xDEAD

Указывает ассемблеру хранить 2 байта (DW - Определить слово (16 бит), между прочим - DB = 8 бит, DD = 32 бита) и использовать a, чтобы указать на него.Поскольку (держу пари, что вы используете компьютер с архитектурой x86-64, это 'little endian', что означает, что он хранит многобайтовые значения, начиная с младшего байта, поэтому в памяти ваше значение 0xDEAD будет сохранено следующим образом: 0xAD first, 0xDE далее.Так как ваш сегмент данных наверняка будет дополнен, скажем, 16 байтами (например), он, вероятно, дополнен нулями.Теперь, если мы предположим, что ваш сегмент данных составляет 16 байтов - первые 2 определяют вашу переменную a - остальные будут равны нулю.

Теперь сегмент данных выглядит следующим образом (при условии заполнения нуля до 16 байтов) (шестнадцатеричные значениябез префикса 0x):

AD, DE, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0
    ^
     \__ (a+1) points here at DE

Написав dword ptr [a + 1], вы говорите ассемблеру, чтобы он закодировал такую ​​инструкцию машинного кода таким образом, чтобы захватить dword (4 байта) с адреса a+1.Это будут байты: DE, 0, 0, 0 Поскольку (как я уже говорил ранее) x86 имеет младший порядок байтов, эти 4 байта, если считать 4-байтовое значение, означают 0x00000DE, следовательно, EAX равно этому значению.

OfКонечно, ваш сегмент данных может быть не 16 байтов, но, вероятно, имеет полную длину страницы, но это бессмысленно.

1 голос
/ 15 марта 2019

Даже если ваш компьютер превращается в дымящуюся пустыню, это «определено» для сборки. «Тип приведения» dword в mov eax, dword [a + 1] просто сообщает ассемблеру, что вы знаете, что делаете, и не хотите получать предупреждение или ошибку. В объектном файле типы исчезли, и процессор не знает, что вы переместили больше байтов, чем определено.

Процессор считывает 4 байта с адреса a + 1, и случайным образом или не случайно значения DE 00 00 00. Как эти нули попали туда, не имеет значения. Может случиться так, что NASM имеет выровненный текстовый сегмент, может быть, операционная система запросила целую страницу (4096 байт) для сегмента данных и заполнила остальные нули, возможно, текстовый сегмент начинается с нулей, потому что точка входа дальше назад. Также возможно, что в какой-то момент поведение программы будет меняться случайным образом.

TLDR: не делай этого!

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