0

So I'm working on a simple game just to teach myself linux x64, and I'm trying to move a value I got from a read call into a parameter in the .data section

My code is as follows (the important stuff is near the bottom):


max_msg_len: 
    .int 30
input: 
    .zero 30
action_msg: 
    .asciz "what will you do? 1. purchase 2. sell 3. haggle\n"
    .equ action_msg_len, . - action_msg
temp_msg:
    .ascii "Value is: "
    .equ temp_msg_len, . - temp_msg
newline: # so I can write just a new line
    .byte 10
action: 
    .byte 0
amount: 
    .int 0 
money:
    .int 20
score:
    .int 0
life:
    .int 1 

.text
    .globl main
main:
get_input:
    #write(STDOUT, action_msg, action_msg_len)
    mov $action_msg_len, %rdx
    mov $action_msg, %rsi
    mov $1, %rdi
    mov $1, %rax
    syscall

    #read(STDIN_FILENO, input, max_msg_len)
    mov $max_msg_len, %rdx
    mov $input, %rsi
    mov $0, %rdi
    mov $0, %rax
    syscall

    #write(STDOUT_FILENO, temp_msg, temp_msg_len)
    mov $temp_msg_len, %rdx
    mov $temp_msg, %rsi
    mov $1, %rdi
    mov $1, %rax
    syscall

    #write(STDOUT_FILENO, action, max_ms)
    mov $1, %rdx
    mov $action, %rsi
    mov $1, %rdi
    mov $1, %rax
    syscall

    #write(STDOUT_FILENO, newline, 1)
    mov $1, %rdx
    mov $newline, %rsi
    mov $1, %rdi
    mov $1, %rax
    syscall

# these are the offending lines
    movb $input, $action

/* I tried to get it to work with registers first, this also doesn't work
    movb $action, %al
    movb $input, %bl */

action_1:
#purchase

action_2:
#sell

action_3:
#haggle

loop:
# if life == 0
# jmp to end
# else
# jmp to get_input

end:

    #exit(0)
    mov $0, %rdi
    mov $60, %rax
    syscall

Essentially what I want to do is move the first byte of input to the action parameter so that I can then do a comparison. and jump to the different actions.

When I assemble the code above as is (with gcc -no-pie) I get

crack_self.s: Assembler messages:
crack_self.s:65: Error: unsupported instruction `mov'

When I try to put the values into a register first, see the comment, I get the following error instead

/tmp/cceFdz3A.o: in function `get_input':
(.text+0x97): relocation truncated to fit: R_X86_64_8 against `.data'
(.text+0x99): relocation truncated to fit: R_X86_64_8 against `.data'
collect2: error: ld returned 1 exit status

I'm not sure if this error means I'm simply not allowed to do this, or if there's some issue with the size of the things I'm moving, or the fact that input is actually 30 bytes and I'm just trying to get the first one.

What is the proper way to do this? I can't find good documentation or examples on the topic. I just find bits and pieces on different pages that don't give me the full picture

Thanks

Dyskord
  • 365
  • 5
  • 14
  • 1
    No instruction can ever have an immediate destination. That's like `&foo = &bar;` in C which can't work either. You also don't want to put the low 8 bits of an address into a register, you want to load the data. `movzbl input(%rip), %eax` for example to load from it. Look at compiler output for `action = input` in C with those declared as `extern char action;` and so on. – Peter Cordes Apr 13 '22 at 02:35
  • thank you! i will try to write my program in c and look at it for clues. Would you mind explaining what movzbl does over the standard mov? thanks – Dyskord Apr 13 '22 at 02:55
  • Okay, I have another question. When I compiled my C program I figured out how to do the mov I wanted to do, but I saw another thing that I don't understand. why is there no $actoin` in the `movb %al, action(%rip)` that get's done? doesn't the $ mean we're getting the address and no $ means we're getting the value stored at the location? – Dyskord Apr 13 '22 at 03:06
  • See one of the linked duplicates, [How to load a single byte from address in assembly](https://stackoverflow.com/q/20727379) and/or google `site:stackoverflow.com movzbl ATT` to find [What does the MOVZBL instruction do in IA-32 AT&T syntax?](https://stackoverflow.com/q/9317922); it's AT&T syntax for movzx, loading a byte and zero-extending it into a register. – Peter Cordes Apr 13 '22 at 03:07
  • Re: the byte store: yes, exactly, you want to update the value in memory to be the destination, not the address itself. So the destination operand is memory, not an immediate. You can't modify an address, only the bytes at that address. – Peter Cordes Apr 13 '22 at 03:08

0 Answers0