Есть ли символ, который представляет текущий адрес в сборке GNU GAS? - PullRequest
15 голосов
/ 24 января 2012

Мне любопытно узнать, существует ли какой-либо специальный синтаксис GAS для достижения того же, что и в примере с NASM:

SECTION .data       

    msg:    db "Hello World",10,0  ; the 0-terminated string.
    len:    equ $-msg              ; "$" means current address.

Особенно меня интересует символ $, представляющий текущий адрес.

Ответы [ 3 ]

22 голосов
/ 07 июля 2012

Выдержка из info as (GNU Binutils 2.21.90) или онлайн в руководстве по ГАЗУ: https://sourceware.org/binutils/docs/as/Dot.html

5.4 Специальный символ точки

Специальный символ . относится к текущему адресу, который as сборка в. Таким образом, выражение melvin: .long . определяет melvin содержать свой собственный адрес.

Присвоение значения . обрабатывается так же, как директива .org. Таким образом, выражение .=.+4 совпадает с выражением .space 4.

msg:    .ascii "Hello World!\n"       # not zero-terminated, use .asciz for that
msglen = . - msg                      # A .equ directive would be equivalent

- это GAS-версия той же идиомы, используемой в NASM (len equ $ - symbol), идиоматический способ заставить ассемблер вычислять длину чего-либо для вас.

5 голосов
/ 24 января 2012

Здесь есть полезное сравнение между газом и NASM: http://www.ibm.com/developerworks/linux/library/l-gas-nasm/index.html

Смотрите, в частности, эту часть, которая, я думаю, решает ваш вопрос:


В листинге 2 также представлена ​​концепция счетчика местоположений (строка 6). NASM предоставляет специальную переменную (переменные $ и $$) для управления счетчиком местоположений. В GAS нет способа манипулировать счетчиком местоположений, и вы должны использовать метки для вычисления следующего места хранения (данных, инструкций и т. Д.). Например, чтобы вычислить длину строки, вы должны использовать следующую идиому в NASM:

prompt_str db 'Enter your name: '
STR_SIZE equ $ - prompt_str     ; $ is the location counter

$ дает текущее значение счетчика местоположений, а вычитание значения метки (все имена переменных являются метками) из этого счетчика местоположений дает число байтов, присутствующих между объявлением метки и текущим местоположением. Директива equ используется для установки значения переменной STR_SIZE для выражения, следующего за ней. Подобная идиома в ГАЗЕ выглядит следующим образом:

prompt_str:
     .ascii "Enter Your Name: "

pstr_end:
     .set STR_SIZE, pstr_end - prompt_str

Конечная метка (pstr_end) дает следующий адрес местоположения, а вычитание начального адреса метки дает размер. Также обратите внимание на использование .set для инициализации значения переменной STR_SIZE для выражения, следующего за запятой. Соответствующий .equ также может быть использован. Альтернативы директиве set GAS в NASM нет.


4 голосов

Пример использования .

Минимальный явный пример:

x: .long .
mov x, %eax
mov $x, %ebx
/* eax == ebx */

Общее сочетание для длин строк:

s: .ascii "abcd"
s_len = . - s
mov $s_len, %eax
/* eax == 4 */

*Синтаксис 1012 * объяснен на Есть ли разница между присвоением знака равенства "x = 1" и ".equ x, 1" или ".set x, 1" в сборке GNU Gas?

Это может быть использовано конкретно, например, в минимально работоспособном автономном примере Linux x86 .

Бесконечный цикл:

jmp .
...