метка
А метка почему помещается в регистр?
И почему это подписано, как "указатель"?
ovf
ты просишь ассемблер запихнуть в вывод байты "Hello, world!\n" и пометить их начало с msg
ovf
метка -- это адрес
ovf
mov $msg,%eax это то же, что mov $1234,%eax
ovf
т.е. это адрес начала строчки
т.е. это адрес начала строчки
А зачем тогда в этой же метке и len?
Или он не в ней?
ovf
len не ассемблируется, это просто ассемблерная переменная
ovf
извини, получился немного каламбур. "ассемблируется" -- в смысле записывается в выходной файл
Ну msg
🦥Alex Fails
И через поиск по хештегу #book
Я неоч понял
ovf
на время забудь про msg:
ovf
.ascii (кстати, есть .asciz) выводит строчку в файл
ovf
= (оно же .equ) просто присваивает внутри ассемблера значение переменной
ovf
теперь можешь вспомнить про msg:. ты создаешь символ с именем msg, которому присваевается текущий адрес в выводе (то же, что .). т.к. дальше ты просишь ассемблировать строчку, то в msg получается адрес её начала
Я думал, просто len тоже как-то к msg относится
ovf
отступы в gas не учитываются
Отступы не для асма
ovf
относится тем, что это длина строчки по адресу msg
А для программиста
Ладно, я понял
ovf
ну это просто такой исторически сложившийся стиль программирования, в очень старых ассемблерах метки были слева, а всё остальное правее
ovf
но метка -- это не начало блока до следующей, это точка
ovf
т.е. считай, что в начале каждой строки по метке, только почти все не используются
分解物質
алсо, то же самое, но по человечески: format ELF executable entry start segment readable msg db 'Hello world!',0xA msg_size = $-msg segment readable executable start: mov eax,4 mov ebx,1 mov ecx,msg mov edx,msg_size int 0x80 mov eax,1 xor ebx,ebx int 0x80
分解物質
а вот без лишнего: format ELF64 executable mov rdx, msglen mov rsi, msg mov rdi, 1 mov rax, 1 syscall xor rdi, rdi mov rax, 60 syscall msg db 'Hello world!',0xA msglen = $-msg
分解物質
fasm
Linux , если чо
.data msg: .ascii "Hello, world!\n" len = . - msg fname: .ascii "out.txt" .text .global _start _start: movl $5, %eax # системный вызов № 4 — sys_open movl $fname, %ebx movl $100, %ecx movl $00700, %edx int $0x80 movl %eax,%ebx movl $4, %eax movl $msg, %ecx movl $len, %edx int $0x80 movl $1, %eax # системный вызов № 1 — sys_exit xorl %ebx, %ebx # выход с кодом 0 int $0x80 # вызов ядра чому не работает?
файл создает, но туда не пишет
i686
Dmitry
может sys_close еще вызвать нужно
Режим 101 нужно было
Dmitry
аааа
А то 100 O_CREAT , нужно было 1 еще добавить O_WRTONLY
Dmitry
теперь пишет?
Dmitry
ну и замечательно
А еще, как писать в юникоде?
точно также
.ascii "юникод"?
分解物質
ой лол
分解物質
в fasm работает
分解物質
.ascii "юникод"?
попробуй
分解物質
分解物質
А вот на си char спокойно русский текст хранит
Dmitry
а что получается-то в итоге? не компилируется? что-то не то выводит?
Dmitry
ну покажи, как пишешь, и покажи, что он тебе пишет
Dmitry
на кириллицу ругается?
Dmitry
значит, гнутый ассемблер - лох :) \uNNNN тоже не воспринимает?
Dmitry
но даже если воспринимает, это же идиотизм писать всё через \u
Директива же .ascii
Он и не обязан воспринимать
Dmitry
ну, я думал, здесь .ascii в значении просто "мультибайт"
Лел
Работает
Dmitry
что работает? \u?
Я где-то в другом месте знач косячил
Просто утф8 буквы
Dmitry
а, ну вестимо в другом месте косячил, да
ovf
$ cat t.s .macro sc n;mov $\n,%rax;syscall;.endm .globl _start;_start:mov $1,%rdi;mov $s,%rsi;mov $n,%rdx;sc 1;xor %rdi,%rdi;sc 60 s:.ascii "что не так с gas?\n";n=.-s $ gcc -nostdlib t.s $ ./a.out что не так с gas?
ovf
у as неудобно, что вывод называется a.out, а не t.o. а as -o t.o t.s;ld t.o уже лень писать
ovf
а вообще скорее всего просто привычка писать gcc -nostdlib, т.к. обычно у меня что-нибудь на си тоже написано