Mixing an assembly using parameters

I am experimenting with the built-in Rust build function on x86_64 Linux. I wrote a simple program that calls syscall exitwith a value of 23.

#![feature(asm)]

fn main() {
  unsafe {
    asm!(
      "
      mov $$60, %rax
      mov $$23, %rdi
      syscall
      "
      :
      :
      : "%rax", "%rdi"
    );
  }
}

This program works fine, I can rustc exit.rs; ./exit; echo $?get 23. Now I want to make asm code interface with rust. So I pass 23 out of rust, not hardcoding in the assembly.

#![feature(asm)]

fn main() {
  unsafe {
    asm!(
      "
      mov $$60, %rax
      mov $0, %rdi
      syscall
      "
      :
      : "r"(23)
      : "%rax", "%rdi"
    );
  }
}

It works again. Now I am trying to pass 23 in the use of a variable.

#![feature(asm)]

fn main() {
  let x = 23i;
  unsafe {
    asm!(
      "
      mov $$60, %rax
      mov $0, %rdi
      syscall
      "
      :
      : "r"(x)
      : "%rax", "%rdi"
    );
  }
}

And it breaks. It comes out with 60, not 23. Looking at the generated assembly, you will learn why:

movq    $23, (%rsp)
movq    (%rsp), %rax
#APP

movq    $60, %rax
movq    %rax, %rdi
syscall

The compiler tries to save 23 in %rax, but then %raxgets overwritten by 60 in the built-in assembly.

So is this a compiler error? Or am I just not right now, how do I use the built-in assembly? (The latter is quite possible).

: LLVM IR:

; ModuleID = 'exit.0.rs'
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: uwtable
define internal void @_ZN4main20h2dd3717eeddb6da6eaaE() unnamed_addr #0 {
entry-block:
  %x = alloca i64
  store i64 23, i64* %x
  %0 = load i64* %x
  call void asm "\0A      mov $$60, %rax\0A      mov $0, %rdi\0A      syscall\0A      ", "r,~{%rax},~{%rdi},~{dirflag},~{fpsr},~{flags}"(i64 %0), !srcloc !0
  ret void
}

define i64 @main(i64, i8**) unnamed_addr #1 {
top:
  %2 = call i64 @_ZN2rt10lang_start20h6ebacfb5a732c9b9PfyE(i8* bitcast (void ()* @_ZN4main20h2dd3717eeddb6da6eaaE to i8*), i64 %0, i8** %1)
  ret i64 %2
}

declare i64 @_ZN2rt10lang_start20h6ebacfb5a732c9b9PfyE(i8*, i64, i8**) unnamed_addr #1

attributes #0 = { uwtable "split-stack" }
attributes #1 = { "split-stack" }

!0 = metadata !{i32 21}
+4
1

, @pczarn github. , "rax", "rdi" not "%rax", "%rdi".

+3

Source: https://habr.com/ru/post/1568501/


All Articles