1

I'm trying to run a test program the prof gave us for 64- bit assembly, and it's not worker properly.

the error is: error LNK2017: 'ADDR32' relocation to 'naturals' invalid without /LARGEADDRESSAWARE:NO fatal error LNK1165: link failed because of fixup errors

The code is:

; no need for .386, .586, .MODEL directives in 64-bit programs

.DATA

sentence BYTE "Now is the winter of our discontent", 0h
firstWord BYTE 20 DUP (?)
space BYTE ' '

naturals QWORD 10 DUP (?)
sum QWORD ?

.CODE

main proc

    ; test out our getFirstWord procedure

    ; the second argument
    mov rax, offset firstWord
    push rax

    ; the first argument
    mov rax, offset sentence
    push rax

    call getFirstWord

    ; initialize our 'naturals' array
    mov rcx, 1
    mov rdi, 0

nextNumber:

    mov naturals[rdi*8], rcx



    inc rcx

    cmp rcx, 10
    jg initializationComplete

    inc rdi

    jmp nextNumber

initializationComplete:

    ; test out our sumArray procedure

    ; second argument (number of elements in array)
    mov rax, 10
    push rax

    ; first argument (array address, alternative to offset)

    lea rax, naturals
    push rax

    call sumArray

    ; store the result in memory
    mov sum, rax

    ; exit

    mov rax, 0
    ret

main endp

getFirstWord proc

    ;pop rax ; address of sentence
    ;pop rbx ; address of firstWord

    mov rax, [esp+8]
    mov rbx, [esp+16]
    mov rcx, 0
    mov cl, [space]

nextCharacter:
    cmp [rax], byte ptr 0   ; check for a null-terminator in the sentence
    je allDone

    cmp cl, [rax] ; check for a space in the sentence
    je nullTerminate

    mov dl, [rax] ; copy the current character
    mov [rbx], dl

    inc rax
    inc rbx

    jmp nextCharacter

nullTerminate:

    inc rbx
    mov byte ptr [rbx], 0

allDone:

    ret 16

getFirstWord endp

sumArray proc

    ; get the address of the array
    mov rax, [rsp+8]

    ; get the number of elements in the array
    mov rcx, [rsp+16]

    xor rbx, rbx  ; initialize sum to zero
    xor rsi, rsi  ; initialize counter to zero

nextArrayElement:
    add rbx, [rax]
    add rax, 8

    inc rsi

    cmp rsi, rcx
    je finishedSum

    jmp nextArrayElement

finishedSum:

    mov rax, rbx

    ret 16

sumArray endp

END

I tried setting LARGEADDRESSAWARE to NO, and the program will compile and build, but there's no output. Is there not suppose to be any output and it just needs to run? Or is that setting screwing something up? I also tried changing how naturals is moved, but the only thing that somewhat worked was changing the address setting.

student
  • 57
  • 1
  • 5
  • 2
    You should use `rsp` not `esp`. Also, be aware that standard calling convention in 64 bit mode uses registers to pass first few arguments (but your own code doesn't have to do this.) As for output, I don't see any code for producing output so that's expected. PS: learn to use a debugger – Jester Apr 16 '16 at 18:13
  • 1
    @Jester Actually, your own code has to do this in order for OS stack unwinding to work. – Raymond Chen Apr 16 '16 at 18:14
  • 6
    Besides the other comments, I venture to guess that the line causing the linker error is `mov naturals[rdi*8], rcx` `naturals` is the 64-bit value representing the address of the label. You are using it as a displacement but in 64-bit mode displacement on a memory operand is 32-bits (it gets sign extended to 64-bit) You could do an `lea rsi, offset naturals` and then use something like `mov [rsi+rdi*8], rcx` – Michael Petch Apr 16 '16 at 18:59
  • As for no output, I don't see you doing anything to output any data to the console. – Michael Petch Apr 16 '16 at 19:02
  • What's the default code model for the MSVC toolchain? In Linux, the default code model for all tools is "small": [code and static data (all symbols) are in the low 2G of address space, so they can be addressed using 32bit sign-extended or zero-extended RIP-relative or absolute displacements](http://www.x86-64.org/documentation.html). So you can and should use stuff like `mov eax, offset firstWord`. Also, you could have made your example *much* smaller, since you'd have the same linker error with a tiny example that just had the one `mov naturals[rdi*8], rcx` line. – Peter Cordes Apr 17 '16 at 00:37
  • 1
    @PaulSweatte How is that a duplicate? It's a completely different error – blenderfreaky Dec 24 '19 at 23:45
  • 1
    If you want to verify @MichaelPetch comment above see this: https://www.nasm.us/xdoc/2.15.05/html/nasmdoc8.html#section-8.6.1 – metablaster Sep 05 '21 at 11:15
  • @MichaelPetch Does `naturals[rdi*8]` equal to `[rdi * 8 + naturals]` syntactially, `rdi` being **index register**, `8` being **scale**, and `naturals` being **displacement**, under MASM? – rosshjb Jul 15 '23 at 06:42
  • 1
    @rosshjb : Yes you can place the displacement inside the square brackets as you are showing as well. `[rdi * 8 + naturals]` and `naturals[rdi * 8]` represent the same thing. – Michael Petch Jul 15 '23 at 06:48
  • @MichaelPetch Thanks! The `[rsi+rdi*8]` seems to be solving the issue by following the format of `[base + index * scale]`. – rosshjb Jul 15 '23 at 07:19

0 Answers0