Получить адрес в конце набора данных?

Я читал книгу «Программирование с нуля», чтобы научиться программировать на ассемблере в Linux. У меня возникли проблемы с решением одного из упражнений в конце главы 3. В упражнении предлагается изменить следующую программу, чтобы использовать адрес в конце набора данных для завершения цикла. Это просто простая программа для поиска максимального числа в наборе данных, в настоящее время она просто использует число ноль, чтобы отметить конец данных.

#PURPOSE:       This program finds the maximum number of a
#               set of data items.
#

#VARIABLES:     The registers have the following uses:
#
#       %edi    --    Holds the index of the data item being examined
#       %ebx    --    Largest data item found
#       %eax    --    Current data item
#
#       The following memory locations are used:
#
#       data_items    --    Contains the item data. A 0 is used
#                           to terminate the data.
#

.section    .data

data_items:
    .long 3, 67, 34, 14, 45, 75, 54, 187, 44, 87, 22, 11, 66, 0

.section    .text

.globl    _start
_start:

movl    $0, %edi                         # Move 0 into the index register
movl    data_items (, %edi, 4), %eax    # Load the first byte of data
movl    %eax, %ebx                      # The biggest

start_loop:

cmpl    $0, %eax                         # Check to see if we've hit the end
je      loop_exit
incl    %edi                            # Load next value
movl    data_items (, %edi, 4), %eax
cmpl    %ebx, %eax                      # Compare values
jle     start_loop                      # Jump to the beginning if new value
                                        # Isn't larger
movl    %eax, %ebx                      # Move the value as the largest
jmp     start_loop                      # Jump to the beginning of loop

loop_exit:

# %ebx is the status code for the exit system call
# and it contains the maximum number
movl    $1, %eax                         # 1 is the exit() system call
int     $0x80

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


person Cole Rowland    schedule 13.10.2012    source источник


Ответы (2)


С небольшими модами для Mac OSX...

.data

data_items:
    .long 3, 67, 34, 14, 45, 75, 54, 187, 44, 87, 22, 11, 66, 0
data_end:

.text

.globl    start
start:
        movl    $0, %edi                       # Move 0 into the index register
        movl    data_items (, %edi, 4), %eax   # Load the first data value
        movl    %eax, %ebx                     # The biggest
        leal    data_end, %ecx                 # Load and save ending address

start_loop:
        leal    data_items(, %edi, 4), %eax    # Get address of next value
        cmpl    %eax, %ecx                     # Check to see if we've hit the end
        je      loop_exit
        incl    %edi                           # Increment index
        movl    (%eax), %eax                   # Load value
        cmpl    %ebx, %eax                     # Compare values
        jle     start_loop                     # Jump to the beginning if new value
                                               # Isn't larger
        movl    %eax, %ebx                     # Move the value as the largest
        jmp     start_loop                     # Jump to the beginning of loop

loop_exit:
        movl    $1, %eax                       # 1 is the exit() system call
        pushl   %ebx
        pushl   $0

        int     $0x80
person DigitalRoss    schedule 13.10.2012
comment
Это очень элегантное решение, но если вы прочтете всего три главы из книги, то сразу его не поймете, а тем более не сможете придумать. Во-первых, правовая инструкция никогда не вводится, а упоминается только в приложениях. Во-вторых, я не уверен, что где-то в первых трех главах объясняется, что data_end, определенный таким образом, будет иметь адрес последнего элемента data_items+1. Мне интересно, действительно ли это ожидаемое решение. Сказав это, вы могли бы обойтись без использования data_end, но я не вижу, как получить доступ к адресу data_items без права. - person means-to-meaning; 31.03.2018
comment
Отлично. Но мы можем удалить pushl %ebx и pushl $0 и дополнительно оптимизировать - person R4444; 17.04.2019

Спросите себя: знаю ли я начальный адрес данных? Откуда я это знаю? Знаю ли я размер данных? Откуда я это знаю? Могу ли я узнать конечный адрес из этой информации?

person Jens Björnhager    schedule 13.10.2012
comment
Это последний вопрос, с которым у меня возникли проблемы. - person Cole Rowland; 13.10.2012
comment
Если вы знаете начальный адрес, количество элементов в данных и размер каждого элемента, вы сможете рассчитать конечный адрес. Вы можете сделать это еще проще, если знаете, как объявлять метки, возможно, вы можете объявить одну рядом с последним элементом? - person Jens Björnhager; 14.10.2012