Search code examples
assemblyx86nasmld

Relocation truncated to fit: R_386_16 against `.bss' - ERROR


When I try to build my assembly code I run into this error:

App.o: in function `_start':
App.asm:(.text+0x8c): relocation truncated to fit: R_386_16 against `.bss'

I compile it using this 2 command:

nasm -f elf32 App.asm

ld -m elf_i386 App.o /usr/local/bin/utils.o -o App

Then I run the App file.


This is my code:

App.asm

%include 'Fun.asm'
%include 'utils.nasm'

section .data
    V   dw  2,-10,13,5,0,1,-9,3
    n   equ ($-V)/2
    d   dw  7

section .bss
    r   resw    1

section .text
global  _start
_start:
    push    V
    push    dword n
    push    word [d]
    push    r
    call    fun
    printw  r
    exit    0

Fun.asm

section .data
    VV  equ 18
    nn  equ 14
    dv  equ 12
    rr  equ 8

section .bss
    g   resb    1

section .text
global  fun
fun:
    push    ebp
    mov     ebp, esp
    pushad                  ;Inizio procedura

    mov     byte [g], 1

    mov     eax, [ebp+VV]   ;EAX(V)
    mov     bx, [ebp+dv]    ;BX(d)
    mov     edi, [ebp+nn]   ;EDI(n)
    xor     dx, dx          ;DX(Somma)

loop1:
    cmp     edi, 0          ;If n<=0 Fine
    jle     fine

    cmp     word [eax], 0   ;If V[i]==0 Cambia gruppo
    je      cmb_grp

    cmp     [eax], bx       ;If V[i]>d Esterno
    jg      esterno
    neg     bx              ;BX=-d
    cmp     [eax], bx       ;If V[i]<-d Esterno
    jl      esterno

    cmp     byte [g], 1     ;If g==1 Avanti
    je      avanti

    add     dx, [eax]       ;Somma+=V[i]
    jmp     avanti

esterno:
    cmp     byte [g], 2     ;If g==2 Avanti
    je      avanti

    add     dx, [eax]       ;Somma+=V[i]
    jmp     avanti

cmb_grp:
    mov     byte [g], 2     ;Passimo a gruppo 2
    mov     [ebp+rr], dx    ;Salviamo somma gruppo 1
    xor     dx, dx          ;Somma=0
    jmp     avanti_

avanti:
    neg     bx              ;BX=d
avanti_:
    add     eax, 2          ;i++
    dec     edi             ;n--

    jmp     loop1

fine:
    sub     [ebp+rr], dx    ;Calcolo risultato

    popad                   ;Fine procedura
    pop     ebp
    ret     14

utils.nasm

; ===============================================================================================
;
; utils.nasm
;
; ===============================================================================================
;
; Libreria di macro di utilità generale. Di seguito si riporta l'elenco dei comandi 
; disponibili, la sintassi e la relativa descrizione.
;
; -----------------------------------------------------------------------------------------------
;   printd <dword>      stampa a video una double word (registro, memoria, immediato)
;               Sintassi specifica:
;               printd dword <immediato_32_bit>
;               printd dword [<indirizzo>]
;               printd <registro_32_bit>
; -----------------------------------------------------------------------------------------------
;   printw <word>       stampa a video una word (reg, mem, imm)
;               Sintassi specifica:
;               printw word <immediato_16_bit>
;               printw word [<indirizzo>]
;               printw <registro_16_bit>
; -----------------------------------------------------------------------------------------------
;   printb <byte>       stampa a video un bye (reg, mem, imm)
;               Sintassi specifica:
;               printb byte <immediato_8_bit>
;               printb dword [<indirizzo>]
;               printb <registro_8_bit>
; -----------------------------------------------------------------------------------------------
;   prints <str>,<len>  stampa a video la stringa di lunghezza <len> 
;               posta in memoria a partire dall'indirizzo <str>
; -----------------------------------------------------------------------------------------------
;   printregs       mostra il contenuto dei registri generali a 32 bit
; -----------------------------------------------------------------------------------------------
;   print<reg>      mostra il contenuto del registro a 32 bit <reg>
;               dove <reg> in {eax, ebx, ecx, edx, esi, edi, ebp, esp}
; -----------------------------------------------------------------------------------------------
;   format_dec      imposta il formato di output a DECIMAL (default)
; -----------------------------------------------------------------------------------------------
;   format_udec     imposta il formato di output a UNSIGNE DECIMAL
; -----------------------------------------------------------------------------------------------
;   format_bin      imposta il formato di output a BINARY
; -----------------------------------------------------------------------------------------------
;   format_hex      imposta il formato di output a HEXADECIMAL
; -----------------------------------------------------------------------------------------------
;   cr_on           abilita a capo nelle stampe (default)
; -----------------------------------------------------------------------------------------------
;   cr_off          disabilita a capo nelle stampe 
; -----------------------------------------------------------------------------------------------
;   exit <code>     termina il programma con codice d'uscita <code>
; ===============================================================================================
;
; Per utilizzare i comandi nel proprio sorgente assembly:
;   1) Includere utils.nasm nel proprio file sorgente con la direttiva:
;       %sseutils "utils.nasm"
;   2) Includere nel link il file oggetto utils.o:
;       ld -m elf_i386 <file>.o utils.o -o <file>
;

section .data

seax    db  'eax = ['
leax    equ $-seax
sebx    db  'ebx = ['
lebx    equ $-sebx
secx    db  'ecx = ['
lecx    equ $-secx
sedx    db  'edx = ['
ledx    equ $-sedx
sesi    db  'esi = ['
lesi    equ $-sesi
sedi    db  'edi = ['
ledi    equ $-sedi
sebp    db  'ebp = ['
lebp    equ $-sebp
sesp    db  'esp = ['
lesp    equ $-sesp
send    db  ']'
scr     db  10
lend    equ 2


oldcr   db  1


extern format
extern cr
extern sprintd
extern buf
extern buflen


%macro  exit    1
    mov eax, 1
    mov ebx, %1
    int 80h
%endmacro


%macro  prints  2
    pushfd
    pushad
    mov eax, 4
    mov ebx, 1
    mov ecx, %1
    mov edx, %2
    int 80h
    popad
    popfd
%endmacro


%macro  printcr 0
    prints      scr, 1
%endmacro


%macro  printbuf    0
    prints  buf, [buflen]
%endmacro


%macro  cr_on   0
    mov [cr], byte 1
%endmacro


%macro  cr_off  0
    mov [cr], byte 0
%endmacro


%macro  cr_save 0
    push    eax
    mov al, [cr]
    mov [oldcr], al
    pop eax
%endmacro


%macro  cr_restore 0
    push    eax
    mov al, [oldcr]
    mov [cr], al
    pop eax
%endmacro


%macro  format_dec  0
    mov [format], byte 0
%endmacro


%macro  format_udec 0
    mov [format], byte 1
%endmacro


%macro  format_bin  0
    mov [format], byte 2
%endmacro


%macro  format_hex  0
    mov [format], byte 3
%endmacro


%macro  printd  1
    pushfd
    pushad
    push    dword 32
    push    %1
    call    sprintd
    add esp, 8
    printbuf
    popad
    popfd
%endmacro


%macro  printw  1
    pushfd
    pushad
    push    dword 16
    mov ax, %1
    movsx   eax, ax
    push    eax
    call    sprintd
    add esp, 8
    printbuf
    popad
    popfd
%endmacro


%macro  printb  1
    pushfd
    pushad
    push    dword 8
    mov al, %1
    movsx   eax, al
    push    eax
    call    sprintd
    add esp, 8
    printbuf
    popad
    popfd
%endmacro


%macro  printeax    0
    cr_save
    cr_off
    prints      seax, leax
    printd      eax
    prints      send, lend
    cr_restore
%endmacro


%macro  printebx    0
    cr_save
    cr_off
    prints      sebx, lebx
    printd      ebx
    prints      send, lend
    cr_restore
%endmacro


%macro  printecx    0
    cr_save
    cr_off
    prints      secx, lecx
    printd      ecx
    prints      send, lend
    cr_restore
%endmacro


%macro  printedx    0
    cr_save
    cr_off
    prints      sedx, ledx
    printd      edx
    prints      send, lend
    cr_restore
%endmacro


%macro  printesi    0
    cr_save
    cr_off
    prints      sesi, lesi
    printd      esi
    prints      send, lend
    cr_restore
%endmacro


%macro  printedi    0
    cr_save
    cr_off
    prints      sedi, ledi
    printd      edi
    prints      send, lend
    cr_restore
%endmacro


%macro  printebp    0
    cr_save
    cr_off
    prints      sebp, lebp
    printd      ebp
    prints      send, lend
    cr_restore
%endmacro


%macro  printesp    0
    cr_save
    cr_off
    prints      sesp, lesp
    printd      esp
    prints      send, lend
    cr_restore
%endmacro


%macro  printregs   0
    cr_save
    printcr
    printeax
    printebx
    printecx
    printedx
    printesi
    printedi
;   printebp
;   printesp
    cr_restore
%endmacro

What could it be?


Solution

  • The problem is the line:

    printw  r
    

    Due to the macro %macro printw 1 in utils.asm, that line will actually cause the following code:

    ...
    mov ax, r
    ...
    

    I don't use nasm, but I assume that nasm interprets this line as:

    "Load the address of r into the register ax."

    This is not possible because the address is a 32-bit value but ax is only 16 bits wide.

    As I have already written, I don't know nasm. Therefore I cannot tell you how you can load the value stored at r into the register ax.

    However, in other assemblers that I know, the following line should do the job:

    printw [r]