0

After storing the results of cpuid in the unallocated memory spaces buff and numb, I would like to append a newline character to each of them. So, I made the unallocated spaces 1 byte longer than necessary.

The whole code is:

section .bss

    buff resb 13
    numb resb 5

section .text
global _start

_start:

    mov eax, 0
    cpuid

    mov dword [numb], eax
    mov dword [buff+0], ebx
    mov dword [buff+4], edx
    mov dword [buff+8], ecx
                           
    mov byte [numb+4], newl
    mov byte [buff+12], newl

    mov rax, 1
    mov rdi, 1
    mov rsi, buff
    mov rdx, 13
    syscall

    mov rax, 1
    mov rdi, 1
    mov rsi, numb
    mov rdx, 5
    syscall

    mov rax, 60
    mov rdi, 0
    syscall

section .data:
    newl: db 0x0A

My attempt to append a newline follows the same syntax used in the previous lines:

mov byte [numb+4], newl
mov byte [buff+12], newl

But the linker generates this error:

$ nasm -f elf64 test_cpuid.s
$ ld -o test_cpuid test_cpuid.o
test_cpuid.o: in function `_start':
test_cpuid.s:(.text+0x2a): relocation truncated to fit: R_X86_64_8 against `.data:'
test_cpuid.s:(.text+0x32): relocation truncated to fit: R_X86_64_8 against `.data:'

How to fix this? Maybe I used a wrong syntax?

BowPark
  • 1,340
  • 2
  • 21
  • 31
  • 1
    Why not just `mov byte [numb+4], 0x0A`? – Some programmer dude Apr 26 '23 at 10:31
  • @Someprogrammerdude Because I would like (if possible) to maintain a label for newline, it looks easier to use for me and with less confusion, instead of typing each time the hex value. – BowPark Apr 26 '23 at 10:34
  • 2
    You're looking for `newl equ 0xa`. Or just use \n inside backticks to get NASM to process C-style escapes. What you've written is using the address as an immediate, because you defined `equ` as a label, not an integer constant. – Peter Cordes Apr 26 '23 at 10:38
  • 2
    Also, if you want to output 18 total bytes of stuff (a 13-byte string, 4 binary bytes?? and another newline), you can just make that contiguous in the order you want and make one `write` system call. Or if you actually wanted to output a text representation of the integer in EAX, see [How to convert a binary integer number to a hex string?](https://stackoverflow.com/q/53823756) / [How do I print an integer in Assembly Level Programming without printf from the c library? (itoa, integer to decimal ASCII string)](https://stackoverflow.com/a/46301894) – Peter Cordes Apr 26 '23 at 10:42
  • @PeterCordes Thank you, it works. Why is this necessary? The address `newl` can't be used in the `mov` line? Also thanks for the reference links. – BowPark Apr 26 '23 at 10:43
  • 2
    The address doesn't fit in 8 bits, so `ld` complains about the impossible relocation when you try to link. But you don't want to store the address in the first place; you want a `0xa` byte. If that's just stored in the .data section somewhere, you'd have to load it into a register before you can store it somewhere else. (Or use one of x86-64's very few instructions that can take two memory operands: [What x86 instructions take two (or more) memory operands?](https://stackoverflow.com/q/52573554) - none of which take two arbitrary *explicit* memory operands, at least one implicit.) – Peter Cordes Apr 26 '23 at 10:46
  • 1
    @PeterCordes Thank you so much: this is very useful and clarifying. – BowPark Apr 26 '23 at 10:50

0 Answers0