Форум русскоязычного сообщества Ubuntu


Считаете, что Ubuntu недостаточно дружелюбна к новичкам?
Помогите создать новое Руководство для новичков!

Автор Тема: GNU assembler  (Прочитано 1354 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн hovey

  • Автор темы
  • Новичок
  • *
  • Сообщений: 11
    • Просмотр профиля
GNU assembler
« : 27 Февраля 2013, 17:04:43 »
Помогите разобраться с некоторыми особенностями синтаксиса этого языка.
1. Для того чтобы сравнить 2 элемента массива мне пришлось использовать 2 регистра под хранение адресов и еще 1 для разадрисации одного из указателей. Можно ли как-нибудь произвести разадрисацию без использования промежуточного регистра?
2. Работает ли разадресация в строке pushl (%edx)? Программа падает при вызове printf..  Пока что не пойму почему.
3. Используя отладчик GDB как получить доступ к данным если в регистре храниться лишь указатель на них. В данном случае указатель на массив.

И буду признателен за любые замечания по коду..
//1, 3, 5, 6, 8, 9
.data /* стек данных        */
printf_format:  /* формат вывода      */
  .string "%d\n"
array_res:
  .long 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
array:
  .long 1, 1, 3, 5, 6, 6, 8, 9, 6, 1
array_end:

.text /* стек кода      */
.globl main /* main доступен извне      */
.type   main, @function /* main не данные, а функция */
main: /* метка main       */
  movl $array, %edx /* адрес начала массива данных в edx */
  movl $array, %ebx /* второй указатель в ebx       */
  movl $array_res, %ecx  /* адрес начала массива флагов в eсx */
  jmp cicl2
  cicl2: /* метка внутреннего цикла           */
   cmpl $array_end, %ebx /* быть может уже конец?       */
   je cicl1 /* в таком случае jmp к внешнему     */
/* циклу      */
   addl $4, %ebx /* увеличим на 4 бита адрес ebx      */
   movl (%ebx), %eax /* разадресуем 1 из указателей       */
/* поместим данные в акамулятор      */
   addl $4, %ecx /* увеличим указатель на флаги на    */
/* 4 бита      */
   cmpl (%edx), %eax /* сравним 2 указателя      */
   je a
   a: movl $0, (%ecx) /* если они равны флаг с тем же      */
                        /* индексом обнуляем      */
   jmp cicl2 /* повторим цикл      */
  cicl1: /* метка 2 цикла      */
   cmpl $array_end, %edx /* быть может уже конец?       */
   je check /* jmp на проверку       */
   addl $4, %edx /* увеличим адрес данных       */
   jmp cicl2 /* прыжок на вложенный       */
  check: /* метка проверки      */
   movl $array, %edx /* загружаем адрес      */
   movl $array_res, %ebx/* загружаем адрес      */
   jmp cicl3
  cicl3:
   cmpl $1, (%ebx) /* если метка = 1      */
   je cprintf /* jmp -> вывод на экран      */
   cmpl $array_end, %edx
   je end
   addl $4, %edx /* указатель на след элемент массива */
   addl $4, %ebx /* указатель на след элемент массива */
   jmp cicl3 /* повторить      */
  cprintf: /* метка вывода       */
   pushl (%edx)
   pushl $printf_format
   call printf
   movl %esp, 0x00010000
   cmpl $array_end, %edx
   je end
   addl $4, %edx
   addl $4, %ebx 
   jmp cicl3
  end:
   movl  $1, %eax
   movl  $0, %ebx
   int   $0x80
update
в качестве книги был использован сайт
http://ru.wikibooks.org/wiki/%D0%90%D1%81%D1%81%D0%B5%D0%BC%D0%B1%D0%BB%D0%B5%D1%80_%D0%B2_Linux_%D0%B4%D0%BB%D1%8F_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%81%D1%82%D0%BE%D0%B2_CВозможно я не внимательно читал, но ответов на данные вопросы я не нашел...
« Последнее редактирование: 27 Февраля 2013, 17:11:26 от hovey »

Оффлайн topspin

  • Участник
  • *
  • Сообщений: 103
    • Просмотр профиля
Re: GNU assembler
« Ответ #1 : 01 Марта 2013, 20:17:47 »
твоя терминология относится к языку высокого уровня в асме используется тоько адрес и значение по этому адресу
разадресация это наверное разыменование
вообще не понятно что делает программа
адрес увеличивается не на 4 бита а на 4 байта
зачем здесь массив флагов?
если ты используешь printf функцию то надо параметры ее загонять в стек командой pushl
« Последнее редактирование: 01 Марта 2013, 20:57:09 от topspin »

Оффлайн hovey

  • Автор темы
  • Новичок
  • *
  • Сообщений: 11
    • Просмотр профиля
Re: GNU assembler
« Ответ #2 : 04 Марта 2013, 12:49:52 »
В программе находится массив из 10 элементов, она должна удалить повторяющиеся элементы и вывести его на экран.
Массив флагов для того чтоб не резервировать значение в исходном массиве под флаг..

Пользователь решил продолжить мысль 04 Марта 2013, 12:53:01:
если ты используешь printf функцию то надо параметры ее загонять в стек командой pushl
так и поступаем. но все равно программа падает на строке printf
Цитировать
pushl (%edx)
pushl $printf_format
« Последнее редактирование: 04 Марта 2013, 12:53:01 от hovey »

Оффлайн topspin

  • Участник
  • *
  • Сообщений: 103
    • Просмотр профиля
Re: GNU assembler
« Ответ #3 : 07 Марта 2013, 20:07:45 »
pushl (%edx)
надо в стек загнать адрес первого элемента массива а не значение его-

pushl %edx

честно говоря я не очень понял сам алгоритм

 

Страница сгенерирована за 0.045 секунд. Запросов: 25.