0

I just started learning Assembly using Linux GNU and I am in the beginning stages to learning. Below is an simple code used in the book "Programming from the Ground up".

.section .data
data_items:
 .long 3,67,34,222,45,75,54,34,44,33,22,11,66,0

.section .text
.globl _start
_start:

        movl $0, %edi
        movl data_items(,%edi,4), %eax
        movl %eax, %ebx

start_loop:
        cmpl $0, %eax
        je loop_exit
        incl %edi
        movl data_items(,%edi,4), %eax
        cmpl %ebx, %eax
        jle start_loop
        movl %eax, %ebx
        jmp start_loop
loop_exit:

   movl $1, %eax
   int  $0x80

We're working on indirect addressing mode. I'm trying to modify this program to change the first value in the array to be the largest value (without, of course, changing the first data values in the code. Currently, the max value is 222. I tried to put an indirect address mode for line 9 from

movl %eax, %ebx
%ebx, %eax

to

movl (%eax), %ebx
%ebx, (%eax)

I assembled, linked, and ran the code, and the result was

Segmentation fault (core dumper)

and after echo $?, I got the value 139.
I read that "Segmentation fault" means that you tried to access memory that you do not have access to. I'm just trying to understand how to change the first number to be the max value in the array.

Sorry, I'm just starting with this.

Update: I solved it on my own. It's in the comment below.

  • why are you doing a system call ? (int x80) EDIT the question now that i see you load the eax is, what is system call 1 ? ALSO are you sure about your array indexing at 4 for the forst value ? Does it not start from 0 ? Not that this would be the matter but just to know. – Yvain Mar 22 '21 at 03:27
  • I don't get it why you assign a constant to index the array if you are dynamically looping on it to find the highest value. It seems to me like you need to start with some higher level languages. – Yvain Mar 22 '21 at 03:40
  • `movl (%eax), %ebx`: So when `%ebx` is 3 and `%eax` is 67, you are trying to take whatever value is at *address* 67 in memory and load it into `%ebx`. That is surely not what you want; there is nothing useful at address 67 (and indeed it's not even accessible to you, as witnessed by your segfault). – Nate Eldredge Mar 22 '21 at 03:48
  • It seems to me that you will only know what the max value was after the loop has finished, i.e. when you get to `loop_exit`. What register will it be in? At what location in memory do you want it to be stored? – Nate Eldredge Mar 22 '21 at 03:49
  • @Yvain: The 4 is a scale, not a displacement. This is the equivalent of Intel-syntax `mov eax, [data_items + 4*edi]` which seems correct when `edi` is the index into the array. And system call 1 is `_exit`; this is to terminate the program. – Nate Eldredge Mar 22 '21 at 03:51
  • 1
    I'm a bit unclear on the goal. Are you just supposed to *replace* the first array entry with the largest value? I'm not sure how indirect addressing would be useful for that (unless they're thinking of any memory operand as "indirect"). Are you supposed to *swap* it with the largest value? – Nate Eldredge Mar 22 '21 at 03:53
  • What strucks me is that you never seems to be modifying the array. Also you only compare the first value of the array with the others, to test them all you need a loop in a loop. – Yvain Mar 22 '21 at 03:55
  • you need to get the highest value of the array and so compare them all and then put the winner at position 0. – Yvain Mar 22 '21 at 04:02
  • I appreciate the response. To make it plain without going over my own head, I have to modify the code that was stated at the beginning of my post. Modify it so that it changes the first value in the array (which would 3) to a new maximal value by way of "indirect addressing" without manually altering the first data item. I hope that helps. I'm learning as I go, but I'm assuming I have to add a function to change the value of 3 to a number higher than 222. Currently the program shows the high value at 222 as designed when assembled, link and ran the larger value is 222. – King James Mar 23 '21 at 22:43
  • I believe I have to use the leal load effective address instruction by loading an effective address into an address register. don't know much about leal though. I not sure how leal works though – King James Mar 23 '21 at 23:55
  • Instead of ' movl %eax, %ebx ' I replaced it with with ' leal 225(%eax), %ebx ' which gave me 228 as the new largest number in the array instead of 222. Adding editing that line allowed 225 to be added to the first number in the array which is 3. The indirect addressing was used for ' (%eax) ' – King James Mar 24 '21 at 00:42
  • You can post an answer to your question (click "answer your own question), instead of editing a note into the question itself. But note that `lea 225(%eax), %ebx` just does EBX = EAX + 225 ([Using LEA on values that aren't addresses / pointers?](https://stackoverflow.com/a/46597375)). That only happens to be right because of the data that's in the array. You might as well have done `movl $228, data_items` to just store a constant into the first dword of the array, or `addl $225, data_items` to add 225. – Peter Cordes Mar 24 '21 at 19:22
  • @Peter Cordes - True, but the assignment required the leal command to complete the task. Thanks! – King James Mar 24 '21 at 21:48
  • BTW, `leal` is just LEA with an `l` (dword) size suffix, already implied by using a 32-bit destination register. If an assignment / problem tells you to use `lea`, they might be intending that you use it for pointer math. IDK why, though; `mov $data_items, %edi` is a more efficient way to put a pointer into a register than `lea data_items, %edi`, and `lea 4(%edi), %edi` to increment a pointer has no advantage over `add $4, %edi`. – Peter Cordes Mar 24 '21 at 22:15

0 Answers0