0

having this:

.text
    .globl main
str:
    .string "hello world"
len = .-str #a strange assignment
main:
    mov $1, %eax
    mov $1, %edi
    movabs $str, %rsi
    mov $len, %rdx
    syscall 
    call exit

1) here is str with colons (as I see usually), but then len is assigned by =. I do not think that is because the str is address, and len is number (and thus different type), but why one can be assigned different ways? Or are both labels?

2) Why to use mov str(%rip), %rsi, when I can use movabs $str, %rsi?

autistic456
  • 163
  • 7

1 Answers1

1

Labels are followed by :

An = isn't a label, it defines a symbol as an assemble-time constant the way .set or .equ does. This is getting the assembler to calculate the length of the string for you, at assemble time.

. is the current position. Think of . as an implicit label at the start of this line. You could equivalently have put a str_end: label after the string and done len = str_end - str.


Why to use mov str(%rip), %rsi, when I can use movabs $str, %rsi?

Those aren't equivalent! mov str(%rip), %rsi would load 8 bytes from that address, getting the string data into a register. But you need a pointer to the string in a register as an arg for a write(int fd, void *buf, size_t len) system call. Try it in a debugger and/or strace and watch it fail.

That's why the movabs in this code uses $str, to get the address as a 64-bit immediate.

However, that's the worst way to put a label/symbol address into a register. movabs with an 8 byte immediate amounts to a 10-byte instruction total, and being absolute it needs runtime fixups in a PIE executable or library (ELF shared object) when the loader chooses an actually base address for the executable.

You actually want LEA str(%rip), %rsi (7 bytes), or in a non-PIE Linux executable where static addresses fit in the low 31 bits of address space, mov $str, %esi.

Peter Cordes
  • 245,674
  • 35
  • 423
  • 606
  • sory, no *double* colon. I have mistyped. But anyway, if `=` is the same (or similar) to `.set`, then Why i can *not* do `len: .set .-str`? – autistic456 Jun 07 '20 at 10:25
  • @autistic456: Because that's not the syntax for `.set`. (https://sourceware.org/binutils/docs/as/Set.html). It would be `.set len, . - str`. .set is a directive. – Peter Cordes Jun 07 '20 at 10:26
  • Ok, and then how differ `lea str(%rip), %rsi` from `movabs $str, %rsi`. Both are loading addres – autistic456 Jun 07 '20 at 10:27
  • @autistic456: read the [How to load address of function or label into register in GNU Assembler](https://stackoverflow.com/q/57212012) Q&A I linked. 7-byte RIP-relative LEA is shorter and more efficient, and position-independent. – Peter Cordes Jun 07 '20 at 10:29
  • Just read it. It seems you explain, the `movasb` is used for jumps, and therefor for first function instruction, but bad for immediate. But still both are *just* address. Once is for data (immediate) and the other for tex (first function instruction), so why does linux supports it? I cannot jump wit `lea toJump(%rip)`? – autistic456 Jun 07 '20 at 10:31
  • @autistic456: uh, no, either work for any label address. (Except in a "large" code model, in which case you might need movabs.) The difference is absolute vs. PC-relative, and in code-size. – Peter Cordes Jun 07 '20 at 10:39
  • so in "large code model", where I want to get to address very high (and therefor use all 8 bytes, the `movabs` manipulate with - or is ti 10 bytes?), then I will use absolute address and not relative. But I can still use relative, it is just a number, so again, Why not use relative address from rip offset (as is `lea toJump(%rip)`) even for "large" code models? – autistic456 Jun 07 '20 at 10:51
  • 1
    @autistic456: because the RIP-relative addressing mode only uses a 32-bit relative displacement, enough to cover 2GiB of code + static data (able to reach any address from any other address). [Referencing the contents of a memory location. (x86 addressing modes)](https://stackoverflow.com/a/34058400) That's why the large code model can't use it. – Peter Cordes Jun 07 '20 at 10:53