1

I am trying to write B to the file, read it, xor it with the integer 10 and write the result to the file, but I get an operand mismatch. How can I xor the value stored in a buffer with an integer and then write the result back to file? Thank you!

.section .bss

buffer: .skip 1

      .align 8
file: .quad 0


.data


B: .byte 0x42

.text
filename: .asciz "file.bmp"
mode: .asciz "w+"
myText: .asciz "C"
toInt: .asciz "%u"




.global main

main:
    pushq   %rbp            
    movq    %rsp, %rbp      

    movq $filename , %rdi      
    movq $mode , %rsi         
    call fopen        

    mov %rax, file 

    mov $B, %rdi 
    mov $1, %rsi 
    mov $1, %rdx 
    mov file, %rcx 
    call fwrite

    mov file, %rdi 
    mov $0, %rsi 
    mov $0, %rdx 
    call fseek 

    mov $buffer, %rdi 
    mov $1, %rsi 
    mov $1, %rdx 
    mov file, %rcx 
    call fread

    movq $10, %r10
    xor %r10, $buffer

    mov $buffer, %rdi 
    mov $0, %rsi 
    mov $0, %rdx 
    mov file, %rcx 
    call fwrite

    movq    %rbp, %rsp     
    popq    %rbp            
    movq    $0, %rdi        
    call    exit 



I tried to move the value from the buffer into an register, but that also doesnt seem to work. Also I tried to change the order of buffer and integer in the xor operation, still no results.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
michael29
  • 31
  • 2
  • Read up on addressing modes. `$buffer` is an immediate addressing mode; you want a direct addressing mode which is just `buffer`. – fuz Oct 30 '22 at 16:45
  • Near duplicate of [What's difference between number with $ or without $ symbol in at&t assembly syntax?](https://stackoverflow.com/q/18996870), and if there's another duplicate that covers loading/storing 8 bytes when you only reserved 1 byte. Although in practice the `.align 8` reserves another 7 not being used by anything else. – Peter Cordes Oct 30 '22 at 17:56

1 Answers1

2

Two issues.

First, the $ prefix in AT&T assembly denotes an immediate value, a constant to be encoded into the instruction. It doesn't make sense to use that as the destination of an instruction; you can't modify a constant. If you want to read or write the contents of memory at a given address, you omit the $. So that suggests something like xor %r10, buffer.

But that is still not right, because of operand size. For most instructions, x86-64 can operate on 8, 16, 32 or 64-bit values. When one of the operands is a register, its size determines the operand size. %r10 is a 64-bit register, so xor %r10, buffer is a 64-bit operation. It will load a 64-bit quadword (8 bytes) from memory location buffer, xor all 64 bits with the corresponding bits of %r10, and write back all 8 bytes. That's not good here because buffer is actually only 1 byte; you can't be sure that the next 7 bytes are even safe to access at all.

So instead of %r10, you want the 8-bit register corresponding to the low 8 bits of %r10, which is called %r10b. (For the legacy registers %rax, %rbx, etc, the low 8 bits are called %al, %bl, etc. See Assembly registers in 64-bit architecture and your architecture reference manual for more info.) Thus xor %r10b, buffer would work.

However, the xor instruction can still take an immediate as its source operand. So you actually don't need a register at all; you can skip loading %r10 and just do

xorb $10, buffer

Since there is no register operand on this instruction, we have to specify the operand size manually, which is what the b suffix in xorb accomplishes. See also https://sourceware.org/binutils/docs/as/i386_002dVariations.html.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • 2
    At the risk of over-complicating things, the normal efficient way to address static storage like `buffer` is with RIP-relative addressing: `xorb $10, buffer(%rip)`. [Why does this MOVSS instruction use RIP-relative addressing?](https://stackoverflow.com/q/44967075) . Or since you need to load the buffer address into a register for the next `fwrite` anyway, `lea buffer(%rip), %rdi` ; `xorb $10, (%rdi)` – Peter Cordes Oct 30 '22 at 17:53
  • The AT&T Syntax tag wiki also has some summary and links about how the syntax works: https://stackoverflow.com/tags/att/info – Peter Cordes Oct 30 '22 at 17:55