Системный вызов чтения газа при нарушении доступа

Я новичок в языке ассемблера и столкнулся с проблемой на первых шагах. У меня есть некоторый опыт работы с языками высокого уровня, но я чувствую себя полным новичком на этом низком уровне.

Я использую ассемблер GNU (газ) версии 2.23 x86_64 в системе Xubuntu.

Я написал простой привет, мир, и теперь я хочу расширить его до следующих функций:

  • чтение ввода с помощью системного вызова 3
  • проверить, больше ли ввод, чем указанный
  • если короче или равно, напечатайте ввод
  • иначе вывести сообщение об ошибке

Если я запускаю код, он работает для более короткого ввода, но если я ввожу больше 5 символов, я получаю нарушение прав доступа.

Я работаю с этим (немецким) руководством.

Вот мой код:

#
# author: linluk
# filename: name.s
#
# usage:
#   $ as name.s -o name.o
#   $ ld name.o -o name
#   $ ./name
# 

.section .data
  hello: .ascii "hello, what is your name?\n"
  err: .ascii "too long!\n"
  name: .ascii ""

.section .text

.globl _start

_start:
  #output
  mov $4, %eax      # 4 syscall write
  mov $1, %ebx      # 1 filedescriptor stdout
  mov $hello, %ecx  # output buffer
  mov $26, %edx     # length of buffer
  int $0x80         # call

  #input
  mov $3, %eax      # 3 syscall read
  mov $0, %ebx      # 0 filedescriptor stdin
  mov $(name), %ecx # address of name
  mov $6, %edx      # max length
  int $0x80

  #check input length
  mov $5, %ebx             #######################
  cmp %ebx, %eax           # <-- HERE or         #
  jg problem #to long      # <-- HERE            #
                           # IS SOMETHING WRONG  #
                           # I GUESS !!          #
  #output of $name         #######################
  mov $1, %ebx
  mov $name, %ecx
  mov %eax, %edx
  mov $4, %eax
  int $0x80

  jmp exit

problem:
  #output of $err
  mov $4, %eax
  mov $1, %ebx
  mov $err, %ecx
  mov 10, %edx
  int $0x80

exit:
  mov $1, %eax      # 1 syscall exit
  mov $0, %ebx      # returnvalue
  int $0x80

person linluk    schedule 10.03.2014    source источник
comment
Вы забыли зарезервировать место для name. Попробуйте: name: .space 6. Ошибка вызвана отсутствием знака $ в строке mov 10, %edx. Научитесь пользоваться отладчиком.   -  person Jester    schedule 10.03.2014
comment
большое спасибо! я попытался загрузить его в gdb, используя $ gdb name, а затем >> start, но он говорит, что нет основной функции... мне нужно научиться использовать отладчик в исходном коде сборки. БОЛЬШОЕ СПАСИБО! :)   -  person linluk    schedule 10.03.2014
comment
Дайте нам дамп регистров (только регистры, а не память) после строки int $0x80 и строки #check input length   -  person User.1    schedule 12.03.2014


Ответы (2)


Мне очень нравится, как вы заранее сделали домашнее задание и показали нам написанный код.

Мне особенно нравится тот факт, что вы прокомментировали свой код; отличный сэр. Теперь я рад помочь (если это действительно полезно).

Хорошо, я сосредоточусь на этом...

mov $5, %ebx             #######################
cmp %ebx, %eax           # <-- HERE or         #
jg problem #to long      # <-- HERE            #
                         # IS SOMETHING WRONG  #
                         # I GUESS !!          #
#output of $name         #######################

Не беспокойтесь; на самом деле ничего плохого. Через это проходят все (в том числе и я).

Ничего себе, с чего мы начнем.

Хорошо, я понял, 15-минутное упражнение, которое прояснит для вас этот вопрос.

Во-первых, вопрос: знакомы ли вы с математикой со знаком в отличие от математики без знака на уровне регистров и битов? Если нет, приготовьтесь к некоторой активности клеток мозга.

Во-вторых, чтобы еще больше запутать вещи, номенклатура и синтаксис ассемблера будут влиять на ожидаемый результат (и на то, что вы получите).

Я действительно не разбираюсь в ассемблере GNU, поэтому позвольте мне объяснить, как я понял это.

Можно подумать, что инструкция Cmp This,That означает что-то вроде...

  • Каково отношение This к That?

Более того, This выше, равно или ниже That?

Пока я буду придерживаться целого числа без знака; потому что это самое простое.

Не уверен насчет GNU, но с другими ассемблерами, когда вы используете беззнаковое мышление в своем мозгу, вы хотите использовать инструкции JA и JB и JE для сравнений.

JA — «Перейти, если выше» JB — «Перейти, если ниже» JE — «Перейти, если равно»

Используемый вами JG может быть арифметическим со знаком; мы будем беспокоиться об этом позже.

Чтобы еще больше запутать ситуацию, синтаксис ассемблера может изменить порядок операндов, и вам придется изменить свое психическое состояние и подумать над этим вопросом вместо исходного...

  • Каково отношение That по отношению к This ?

Хорошо, теперь, устанавливая точки останова, вот как вы можете вовлечь в это свой разум..

 Mov $5, %ebx               # Your original way
 Cmp %ebx, %eax             # Same compare
 Ja problem                 # Unsigned maybe jump


 Mov $5, %ebx               # Same steps
 Cmp %ebx, %eax             # Same steps
 Jb problem                 # Opposite jump sense


 Mov $5, %ebx               # Now, similar steps
 Cmp %eax, %ebx,            # Comparing them in an opposite manner
 Ja problem                 # Watch to see if this jump hits


 Mov $5, %ebx               # Arrange them again
 Cmp %eax, %ebx,            # Backwards compare, but,,,,
 Jb problem                 # Opposite opinion of the flags

В этих четырех примерах предполагается, что два числа (в Ebx и Eax) различны. Если они окажутся одинаковыми, то у нас будет расширенное обсуждение этого вопроса в другой день.

Это, опять же, все о целочисленной арифметике без знака. Для некоторых это было бы элементарно; для других, не волнуйтесь, борьба с путаницей, честно говоря, является нормой. Я знаю, что сделал это.

В любом случае, установите точки останова и запустите каждый из этих трех строковых фрагментов, и подумайте: «...Какова связь ЭТО по отношению к ЭТО ? ..."

По мере того, как вы просматриваете каждый 3-строчный фрагмент, вы поймете эту идею.

Если вы облажаетесь, это будет иметь смысл во второй (или третий, или четвертый, или пятый) раз.

Не уверен, помогает это или нет, просто подумал, что напечатаю это для тех, кто плохо знаком с регистрами, битами, флагами и прочим.

person User.1    schedule 12.03.2014
comment
Спасибо за ваш ответ! у меня была ошибка где-то еще в коде (я забыл $), как упоминал Шут. я надеюсь, что ваш ответ поможет кому-то еще. +1 за работу и потраченное время :) - person linluk; 12.03.2014

Шут ответил:

Вы забыли зарезервировать место для имени. Попробуйте: имя: .space 6. Ошибка вызвана отсутствием знака $ в строке mov 10, %edx. Научитесь пользоваться отладчиком.

Спасибо ему! Теперь это работает.

Я изменил строку name: .ascii "" на name: .space 6
и добавил $ к mov 10, %ebx, чтобы она выглядела как mov $10, %ebx!

person linluk    schedule 12.03.2014