relocation truncated to fit r_386_8 against .bss'

。_饼干妹妹 提交于 2019-12-24 21:42:27

问题


When i type ld -m elf_i386 -o loop loop.asm, i get the error stated in the title, any idea what causes it? Sorry if the code looks bad, fairly new to assembly.

cr equ 13 
lf equ 10 

section .bss
numA resb 1

section .text

global _start:

mov [numA],byte 0
call loop1
jmp endend
loop1:
xor cx,cx
mov al, $numA
cmp cx, 0x0A
jle else 
inc al
jmp end
else:
dec al
jmp end
end:
mov [$numA], al
inc cx
cmp cx,20
jle loop1

endend:
mov dl,$numA
mov ah,2
int 21h

回答1:


In NASM, $numA is the same as numA. A leading $ stops the assembler from considering it as a register name. Thus you can write mov eax, [$eax] to load the eax register from a symbol called eax. (So you could link with C which used int eax = 123;)

So mov [$numA], al looks weird, but it's really just mov [numA], al and isn't the source of the warning.


You're getting the warning from mov dl,$numA which does a mov dl, imm8 of the low byte of the address.

The linker warns you because the address of numA doesn't fit in 1 byte, so the r_386_8 relocation truncated the address.

The _8 tells you it's a relocation that asks the linker to fill in 8 bits. The r_386 tells you it's an i386 relocation as opposed to some type of r_x86_64 relocation (which could be absolute or RIP-relative), or a MIPS jump-target relocation (which would need to right-shift the offset by 2). Possibly related: Relocations in the System V gABI (generic ABI, for which the i386 SysV psABI is a "processor supplement").




回答2:


The fixed code with comments starting ;* about what did I modify:

;* build commands used to test:
;* nasm -f elf32 -F dwarf -g loop.asm -l loop.lst -w+all
;* ld -m elf_i386 -o loop loop.o

cr equ 13
lf equ 10

section .bss
numA resb 1

section .text

global _start   ;* global directive takes symbol name (without colon)

_start:
;* the actual label you defined as global, and want to start from.

    ;* set memory at numA address to byte zero
    mov [numA],byte 0
    ;* try to call subroutine with loop
    call loop1
    jmp endend

loop1:
    xor cx,cx       ;* loop counter = 0
.real_loop: 
;* you don't want to loop to "loop1" as that will reset CX!
    mov al, [$numA] ; load AL with value from memory at numA address
;* in NASM you must use [] to indicate memory load/store
;* the mov al, $numA tried to put the memory address numA into AL
;* but memory address in x86-32 is 32 bit value, and AL is 8 bit only
;* and you didn't want address, but value any way.
    cmp cx, 0x0A
    jle .else 
    inc al
    jmp .end
.else:
;* I modified all subroutine labels to be "local" starting with dot
;* i.e. ".else" is full label "loop1.else". This practice will allow
;* you to use also ".else" in different subroutines, while global
;* "else:" can be used only once per source file.
    dec al
    jmp .end
.end:
    mov [$numA], al
    inc cx
    cmp cx,20
    jle .real_loop      ;* fix of loop jump (to not reset CX)
    ;* after CX will reach value 21, the CPU will continue here
    ret         ;* so added return from subroutine

endend:
    ;* call linux 32b sys_exit(numA value) to terminate
    ;* return value will be equal to zero-extended [numA] to 32bits
    ;* 8bit -1 = 0xFF -> return value is 255
    movzx   ebx,byte [$numA]
    mov     eax,1
    int     80h

After running this:

nasm -f elf32 -F dwarf -g loop.asm -l loop.lst -w+all
ld -m elf_i386 -o loop loop.o
./loop ; echo $?

The output is expected:

255


来源:https://stackoverflow.com/questions/46939146/assembly-relocation-truncated-to-fit-r-x86-64-16-against-data

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!