0

I have a 30k empty string of bytes, I want to write 50 to the 3rd byte and feed it to putchar. I will have a lot of these writes, so I don't want to move 50 to a register first and waste a command. All the offsets are known at compilation time and I just want to put a literal in a command. I tried this:

    .bss
mem:
    .zero 30000
    .text
    .globl main
main:
    pushq %rbp
    movq %rsp, %rbp
    movq $50, mem($3)
    movzbl mem($3), %edi
    call putchar
    leave

It would complain about the literal with the following error: /out2.s:9: Error: 'junk ($3)' after expression

I tried to store the location of mem in a register and operate on that, by changing the code to the following:

    .bss
mem:
    .zero 30000
    .text
    .globl main
main:
    pushq %rbp
    movq %rsp, %rbp
    movq mem, %rbx;  we store the location of mem in %rbx and reuse it later
    movq $50, 3(%rbx)
    movzbl 3(%rbx), %edi
    call putchar
    leave

But this results in a segementation fault. I use gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04), compiling to x86_64-linux-gnu. Any tips?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • You want `movb $50, mem+3` or better `movb $50, mem+3(%rip)`. Not `movq` unless you also want to write the next 7 bytes. `$` shouldn't appear in the addressing mode, especially not inside parens. Also, `movq mem, %rbx` is an 8-byte load from memory because you *didn't* use a `$` to specify an immediate operand (the symbol address); perhaps you were thinking of NASM syntax? [How to load address of function or label into register](https://stackoverflow.com/q/57212012) – Peter Cordes Dec 05 '22 at 19:29
  • You could have used GCC to compile a function that does `mem[3] = 50;` for a global variable `char mem[30000];` e.g. on https://godbolt.org/ – Peter Cordes Dec 05 '22 at 19:41

0 Answers0