Решил чуть-чуть почитать про Ассемблер и что-нибудь закодировать. Честного говоря, думал, что не сумею. Два дня помучился, почти три. Рыл, ковырял, читал, больше искал примеры. Хотел попробовать синтаксис Intel (мне показался несколько более человечным нежели AT&T). Но всё-таки получилось сделать вывод десятичного числа на основе примеров, конечно. Правда, с отправкой остатка в стек не совсем разобрался, как в примерах. Зато сразу вывод с реверсом получился. Code (Text): section .text global _start ;must be declared for using gcc _start: ;tell linker entry point mov eax, 3111;Добавим 1234 - делимое в обратном порядке, то есть 4321. Выводить будем остаток от деления mov edi, 0 loop: inc edi ; Инкремент, чтобы потом записать в строку все значения mov ebx, 10 ; Запишем делитель в цикл, чтобы вернуть ему значение в новой итерации xor edx, edx ; Обнулим остаток div ebx ; Делим add edx, 30h ; Добавим 0 для вывода mov [stroka + edi], edx ;Пишем в строку остаток cmp eax, 0 ; Выходим jne loop ; Возврат в цикл mov ecx, stroka mov edx, 5 ; Размер вывода 5 (видимо, в байтах) mov ebx, 1 ; file descriptor (stdout) mov eax, 4 ; system call number (sys_write) int 0x80 ; call kernel mov eax, 1 ;system call number (sys_exit) int 0x80 ;call kernel section .data segment .bss; stroka resb 5; Хотя, вероятно, лучше положить в цикле остаток в стек?! И затем прочитать каждое значение стека. Ещё странно, если использовать декремент, то потом вывод из буфера будет только одного значения (видимо, что-то не так делаю с декрементом). По идее значения в [stroka + edi] должны записываться в конце строки при декременте, так и есть, и вывод вроде бы правильный, но только одно значение выводится. Видмо, что-то с преобразованием числа (с нулём, может быть ) не додумал. Ассемблер nasm (под Linux 64). Команда сборки и выполнения: nasm -f elf64 print_number.asm -o print_number.o; ld -o print_number print_number.o; ./print_number P.S. Чем-то Ассемблер шахматы напоминает. У меня такая ассоциация. Спасибо всем. Спасибо, что вы есть. Update: Ещё обнаружил, что вызывать ядро стоит 1 раз, а не каждый раз, как было в моём первом примере в цикле. Код отредактировал. Нашёл здесь: https://acm.mipt.ru/twiki/bin/view/Asm/PrintIntFunction Update: Интересно. Если в регистр eax заносить значения из стека, то можно найти первое полезное применение, вроде того: Code (Text): mov eax, [rsp +17] add eax, [rsp +15] Получаем генератор псевдослучайных чисел.
Сделал. Снова почти наугад Если в этой инструкции писать в строку регистр dl (не понял, почему именно его, а не edx целиком) Code (Text): mov [stroka + edi], dl и при этом обратить инкремент регистра edi в декрмент, то строка выводится так как надо. Code (Text): ; Программа печатает целое число ; Работает так: 1) Число делится на 10. 2) В регистр edx заносится остаток, в eax остальная часть. ; 3) Остаток записывается в stroka, начиная с конца, используется декремент, затем выводится ; 4) Если использовать инкремент, то строка будет напечатана в обратном порядке section .data stroka db 4; section .text global _start ;must be declared for using gcc _start: ;tell linker entry point mov eax, 311 ;Добавим 311 - делимое mov edi, 3 loop: dec edi ; Декремент, чтобы потом записать в строку все значения mov ebx, 10 ; Запишем делитель в цикл, чтобы вернуть ему значение в новой итерации xor edx, edx ; Обнулим остаток div ebx ; Делим add edx, 30h mov [stroka + edi], dl ; Пишем в строку остаток в обратном порядке cmp edi, 0 ; Выходим jne loop ; Возврат в цикл mov ecx, stroka mov edx, 4 ; Размер вывода 5 (видимо, в байтах) mov ebx, 1 ; file descriptor (stdout) mov eax, 4 ; system call number (sys_write) int 0x80 ; call kernel mov eax, 1 ;system call number (sys_exit) int 0x80 ;call kernel