Как мне выполнить этот ассемблерный код?

#assembly

#сборка

Вопрос:

Я написал этот простой код на JavaScript и использую d8 для отображения ассемблерного кода. Теперь я хочу выполнить этот ассемблерный код, но я не могу этого сделать.

Вот мой код

 print('Hello')
  

И это сборка, которую я получаю из d8

 --- Raw source ---
print('Hello');


--- Code ---
source_position = 0
kind = FUNCTION
compiler = full-codegen
Instructions (size = 180)
0x13fb4a04740     0  55             push rbp
0x13fb4a04741     1  4889e5         REX.W movq rbp,rsp
0x13fb4a04744     4  56             push rsi
0x13fb4a04745     5  57             push rdi
0x13fb4a04746     6  488b4f2f       REX.W movq rcx,[rdi 0x2f]
0x13fb4a0474a    10  488b490f       REX.W movq rcx,[rcx 0xf]
0x13fb4a0474e    14  83411b01       addl [rcx 0x1b],0x1
0x13fb4a04752    18  41ff75a0       push [r13-0x60]
0x13fb4a04756    22  493ba5200c0000 REX.W cmpq rsp,[r13 0xc20]
0x13fb4a0475d    29  7305           jnc 36  (0x13fb4a04764)
0x13fb4a0475f    31  e8dce2f4ff     call StackCheck  (0x13fb4952a40)    ;; code: BUILTIN
0x13fb4a04764    36  48b80000000004000000 REX.W movq rax,0x400000000
0x13fb4a0476e    46  e86dfcffff     call 0x13fb4a043e0       ;; code: LOAD_GLOBAL_IC
0x13fb4a04773    51  50             push rax
0x13fb4a04774    52  49ba1123f8ee15360000 REX.W movq r10,0x3615eef82311    ;; object: 0x3615eef82311 <undefined>
0x13fb4a0477e    62  4152           push r10
0x13fb4a04780    64  49ba19b92ab6eb2a0000 REX.W movq r10,0x2aebb62ab919    ;; object: 0x2aebb62ab919 <String[5]: Hello>
0x13fb4a0478a    74  4152           push r10
0x13fb4a0478c    76  48ba0000000002000000 REX.W movq rdx,0x200000000
0x13fb4a04796    86  488b7c2410     REX.W movq rdi,[rsp 0x10]
0x13fb4a0479b    91  e820ffffff     call 0x13fb4a046c0       ;; code: CALL_IC
0x13fb4a047a0    96  488b75f8       REX.W movq rsi,[rbp-0x8]
0x13fb4a047a4   100  4883c408       REX.W addq rsp,0x8
0x13fb4a047a8   104  488945e8       REX.W movq [rbp-0x18],rax
0x13fb4a047ac   108  488b45e8       REX.W movq rax,[rbp-0x18]
0x13fb4a047b0   112  48bbd1ba2ab6eb2a0000 REX.W movq rbx,0x2aebb62abad1    ;; object: 0x2aebb62abad1 Cell for 6144
0x13fb4a047ba   122  83430bd1       addl [rbx 0xb],0xd1
0x13fb4a047be   126  791f           jns 159  (0x13fb4a047df)
0x13fb4a047c0   128  50             push rax
0x13fb4a047c1   129  e8fae1f4ff     call InterruptCheck  (0x13fb49529c0)    ;; code: BUILTIN
0x13fb4a047c6   134  58             pop rax
0x13fb4a047c7   135  48bbd1ba2ab6eb2a0000 REX.W movq rbx,0x2aebb62abad1    ;; object: 0x2aebb62abad1 Cell for 6144
0x13fb4a047d1   145  49ba0000000000180000 REX.W movq r10,0x180000000000
0x13fb4a047db   155  4c895307       REX.W movq [rbx 0x7],r10
0x13fb4a047df   159  c9             leavel
0x13fb4a047e0   160  c20800         ret 0x8
0x13fb4a047e3   163  498b45a0       REX.W movq rax,[r13-0x60]
0x13fb4a047e7   167  e9c4ffffff     jmp 112  (0x13fb4a047b0)
0x13fb4a047ec   172  0f1f4000       nop
  

Теперь я хотел бы выполнить этот ассемблерный код, я получаю эту ошибку:

cc -s print.s
print.s:1:1: ошибка: 32-разрядная абсолютная адресация не поддерживается в 64-разрядном режиме

Это мой print.s

 push rbp
movq rbp,rsp
push rsi
push rdi
movq rcx,[rdi 0x2f]
movq rcx,[rcx 0xf]
addl [rcx 0x1b],0x1
push [r13-0x60]
cmpq rsp,[r13 0xc20]
jnc 36
call StackCheck
movq rax,0x400000000
call 0x13fb4a043e0
push rax
movq r10,0x3615eef82311
push r10
movq r10,0x2aebb62ab919
push r10
movq rdx,0x200000000
movq rdi,[rsp 0x10]
call 0x13fb4a046c0
movq rsi,[rbp-0x8]
addq rsp,0x8
movq [rbp-0x18],rax
movq rax,[rbp-0x18]
movq rbx,0x2aebb62abad1
addl [rbx 0xb],0xd1
jns 159
push rax
call InterruptCheck
pop rax
movq rbx,0x2aebb62abad1
movq r10,0x180000000000
movq [rbx 0x7],r10
leavel
ret 0x8
movq rax,[r13-0x60]
jmp 112
nop
  

Комментарии:

1. Как это не по теме?

2. Вы используете OS X, верно? Другие операционные системы допускают абсолютные адреса.

3. Я голосую за то, чтобы закрыть этот вопрос как не относящийся к теме, потому что он основан на такой неверной предпосылке, что нет никакого полезного ответа, кроме «вы не можете взять фрагмент asm из Javascript JIT и выполнить его как отдельную программу». Особенно, когда он печатает что-то вместо того, чтобы просто вычислять входные данные из выходных данных.

4. Спасибо за разъяснение.

Ответ №1:

Вы не можете взять фрагмент из программы с фиксированными указателями, скопировать и вставить его и ожидать, что он сработает.

Ваш фрагмент никогда не будет работать.
Он ссылается на абсолютные адреса, которые действительны только в контексте исходной программы, в которой он был выполнен.
В следующий раз, когда исходная программа будет выполняться, адреса, вероятно, будут другими из-за ASLR, помимо того факта, что все программы в OSX должны быть перемещаемыми; т. Е. фиксированных адресов в OSX не существует.
В любом случае вы указываете на код во время выполнения, которого просто нет в вашем фрагменте копирования-вставки.

Вам нужно научиться писать автономную программу сборки «hallo world».

Существует 100 руководств, подробно описывающих, как это сделать, например: http://peter.michaux.ca/articles/assembly-hello-world-for-os-x

  hello.asm - a "hello, world" program using NASM

section .text

global mystart                ; make the main function externally visible

mystart:

; 1 print "hello, world"

    ; 1a prepare the arguments for the system call to write
    push dword mylen          ; message length                           
    push dword mymsg          ; message to write
    push dword 1              ; file descriptor value

    ; 1b make the system call to write
    mov eax, 0x4              ; system call number for write
    sub esp, 4                ; OS X (and BSD) system calls needs "extra space" on stack
    int 0x80                  ; make the actual system call

    ; 1c clean up the stack
    add esp, 16               ; 3 args * 4 bytes/arg   4 bytes extra space = 16 bytes

; 2 exit the program

    ; 2a prepare the argument for the sys call to exit
    push dword 0              ; exit status returned to the operating system

    ; 2b make the call to sys call to exit
    mov eax, 0x1              ; system call number for exit
    sub esp, 4                ; OS X (and BSD) system calls needs "extra space" on stack
    int 0x80                  ; make the system call

    ; 2c no need to clean up the stack because no code here would executed: already exited

section .data

  mymsg db "hello, world", 0xa  ; string with a carriage-return
  mylen equ $-mymsg             ; string length in bytes
  

Если вы хотите написать ассемблерный код, работающий под OSX, вам также необходимо изучить, как работает OSX API.