Оператор OFFSET
OFF SET можно перевести как “вне набора”. Применительно к языку ассемблера ещё более вольный перевод может звучать так: за пределами набора команд. Почему этот оператор назвали именно так, поймёте, прочитав эту статью. Ну а вообще слово OFFSET переводится как “смещение”. И это, конечно, настоящий перевод. Но я позволил себе немного пофилософствовать )))
Оператор OFFSET возвращает адрес (смещение) некоторой метки данных относительно начала сегмента. Под смещением здесь понимается то количество байтов, которое отделяет метку данных от начала сегмента.
В защищённом режиме работы процессора смещения всегда являются 32-разрядными числами без знака. В реальном и виртуальном режимах адресации смещения всегда 16-разрядные.
С помощью оператора OFFSET в ассемблере можно объявлять переменные, то есть связывать адрес в памяти с именем переменной. По этой ссылке вы найдёте пример объявления строки. Но переменные могут быть, разумеется, не только строковыми.
Здесь мы объявили переменную wVar и назначили сразу ей какой-то значение (в нашем случае 65535). В программе мы записали ЗНАЧЕНИЕ этой переменной в регистр АХ. А вот потом, с помощью оператора OFFSET, мы получаем адрес (смещение) переменной wVar , относительно начала сегмена (в нашем случае это 100h). И в нашем случае смещение будет равно 107 в шестнадцатеричной системе, потому что:
- Сегмент начинается с адреса 100h ( ORG 100h )
- Команда MOV AX, wVar занимает 3 байта с адресами: 100h, 101h, 102h
- Команда MOV DX, OFFSET wVar занимает следующие 3 байта с адресами: 103h, 104h, 105h
- Команда RET занимает 1 байт по адресу: 106h
Ну и получается, что наша переменная wVar находится по адресу 107h.
Таким вот нехитрым образом можно получить адрес первого байта любой объявленной переменной. Соответственно, чтобы получить адрес следующего байта, надо просто прибавить 1 к смещению. Это обычно используется при работе со строками, когда надо получить отдельный символ строки. Пример:
Здесь мы выводим не всю строку, а начиная с 8-го символа, потому что к смещению адреса переменной stroka мы прибавили 7. Но прибавили мы 7, а не 8, потому что адресация начинается с нуля, а не с единицы. Таким образом на экран будет выведено:
то есть только нужная нам часть строки.
На этом пока всё. Подключайтесь к группе Основы программирования в Телеграм, или к другим каналам (ссылки ниже), чтобы ничего не пропустить.
подскажите по ассемблер простыми словами. Что делает команда Offset? и почему символьная константа внутри продолжение.
почему символьная константа message db идет после того как вызвали подпрограмму (прерывание) int 21h?ведь подпрограмму вызвали же уже.
offset означает что берётся адрес переменной, а не её значение. Например, есть переменная:
Предположим, что она размещена по адресу 20FFFh. Тогда:
mov eax, X ;eax = 7
mov eax, offset X ;eax = 20FFFh
+ Почему метка позже и внутри — у Вас судя по виду .com файл, где сегмент данных и сегмент кода (впрочем как и сегмент стека) — один и тот-же и точка входа у него всегда по адресу со смещением 100h
=> Если данные объявлять до начала кода — нужен будет дополнительный прыжок (jmp) чтобы эти данные обогнуть
Offset assembler что это
Ассемблер позволяет определять указатели — переменные, которые хранят адрес других объектов. Для получения адреса объекта применяется выражение
Поскольку адрес в архитектуре x86-64 занимает 8 байт, то для хранения адреса нам надо определить переменную с типом qword . Например, определим переменную и получим ее адрес:
Здесь определена переменная-указатель pn, которая представляет тип qword и которая будет хранить адрес переменной n. Сначала получаем адрес в регистр RAX и затем передаем его в указатель pn:
Если нам надо использовать значение по указателю, можно сначала поместить значение указателя в регистр, а затем использовать косвенную адресацию для получения самого значения по указателю.
В итоге в регистре RAX окажется число 22 — значение переменной n.
При этом мы можем получить адрес уже при определении переменной-указателя:
Указатель необязательно должен представлять переменную — это может быть и константа:
Операции с адресом
При получении адреса мы можем использовать ряд операций:
В этом случае мы можем получить адрес, который смещен относительно адреса переменной на несколько байтов вперед или назад. Выражение переменная [смещение] фактически эквивалентно выражению переменная + смещение . Например:
Здесь переменная nums представляет набор 32-битных чисел. Выражение offset nums возвращает адрес перемнной num — адрес первого числа из этого набора. Соответственно чтобы получить адрес второго числа из этого набора, нам надо прибавить размер одного элемента в байтах, то есть 4 байта — offset nums + 4
What does OFFSET in 16 bit assembly code mean?
I am going through some example assembly code for 16-bit real mode.
I’ve come across the lines:
what is this doing? What does having ‘OFFSET’ there do?
![]()
6 Answers 6
As some of the other answers say, the offset keyword refers to the offset from the segment in which it is defined. Note, however, that segments may overlap and the offset in one segment may be different in another segment. For instance, suppose you have the following segment in real mode
The assembler sees that foo is at offset 0100h from the base of data SEGMENT , so wherever it sees offset foo it will put the value 0100h , regardless of the value of DS at the time.
For example, if we change DS to something other than the base of the data segment the assembler is assuming:
In the second example DS is 0300h , so the base of the segment pointed to by DS is 03000h . This means that ds:[offset foo] points to the address 03000h + 0100h which is the same as 02000h + 01100h , which points to bar .
![]()
It just means the address of that symbol. It’s a bit like the & operator in C, if you are familiar with that.
![]()
offset means that si register will be equal to the offset of the variable value1 (not to its actual value). Offset is the address from the beginning of memory segment where the variable is stored. The offset is usually relative to ds segment (in your case ds and cs registers are pointing to the same segment).
In x86 16bit mode, address space is not flat; instead, addresses are composed of an offset and a «segment». The «segment» points to a 64K space, offset is within that space.
From MASM Programmer’s Guide 6.1 (Microsoft Macro Assembler)
The OFFSET Operator
An address constant is a special type of immediate operand that consists of an offset or segment value. The OFFSET operator returns the offset of a memory location, as shown here:
For information on differences between MASM 5.1 behavior and MASM 6.1 behavior related to OFFSET, see Appendix A.
Since data in different modules may belong to a single segment, the assembler cannot know for each module the true offsets within a segment. Thus, the offset for var, although an immediate value, is not determined until link time.
If you read carefully, the final value is determined after you «link» your object code to create a DLL/EXE. Prior to linking, all you have is an immediate value which represents the offset from the segment’s base address.
![]()
Offset is basically the distance from the segment point(also called datum point). for example segment address is 0000 and the offset or logical address is 0100 then the physical address can be counted by adding the two pairs. Physical Address = 0000+0100=0100 Means that our required location is on the address of 0100. Similarly if segment address is 1DDD and offset is 0100 then : Physical address is : 1DDD+0100=1EDD
Means that our destination is 1EDD.
-
The Overflow Blog
Linked
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.26.43546
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
