Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
294 views
in Technique[技术] by (71.8m points)

macos - Compiling asm file on MacOX with nasm

I am trying to compile asm file on MacOS with nasm.

I do:

nasm -f macho -o file.o file.asm
gcc file.o

and I am getting error:

Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I also tried:

nasm -f macho -o file.o file.asm
ld -o file file.o -arch i386 -lc -no_pie -macosx_version_min 10.12 -lSystem

result is the same error.

This questions didn't help:

Thanks in advance!!

  section         .text

  global          _main
  _main:

  sub             rsp, 2 * 128 * 8
  lea             rdi, [rsp + 128 * 8]
  mov             rcx, 128
  call            read_long
  mov             rdi, rsp
  ; call            read_long
  ; lea             rsi, [rsp + 128 * 8]
  mov             rsi, rdi
  call            add_long_long

  call            write_long

  mov             al, 0x0a
  call            write_char

  jmp             exit

  ; adds two long number
  ;    rdi -- address of summand #1 (long number)
  ;    rsi -- address of summand #2 (long number)
  ;    rcx -- length of long numbers in qwords
  ; result:
  ;    sum is written to rdi
  add_long_long:
  push            rdi
  push            rsi
  push            rcx

  clc
  .loop:
  mov             rax, [rsi]
  lea             rsi, [rsi + 8]
  adc             [rdi], rax ; для вычитание надо сделать spb
  lea             rdi, [rdi + 8]
  dec             rcx
  jnz             .loop

  pop             rcx
  pop             rsi
  pop             rdi
  ret

  ; adds 64-bit number to long number
  ;    rdi -- address of summand #1 (long number)
  ;    rax -- summand #2 (64-bit unsigned)
  ;    rcx -- length of long number in qwords
  ; result:
  ;    sum is written to rdi
  add_long_short:
  push            rdi
  push            rcx
  push            rdx

  xor             rdx, rdx
  .loop:
  add             [rdi], rax
  adc             rdx, 0 ; rdx += кэрри флаг
  mov             rax, rdx
  xor             rdx, rdx
  add             rdi, 8
  dec             rcx
  jnz             .loop

  pop             rdx
  pop             rcx
  pop             rdi
  ret

  ; multiplies long number by a short
  ;    rdi -- address of multiplier #1 (long number)
  ;    rbx -- multiplier #2 (64-bit unsigned)
  ;    rcx -- length of long number in qwords
  ; result:
  ;    product is written to rdi
  mul_long_short:
  push            rax
  push            rdi
  push            rcx

  xor             rsi, rsi
  .loop:
  mov             rax, [rdi] ; мы взяли первые четыре байта числа
  mul             rbx ; если у нас раикс переполнился то мы старшие биты записываются в рсай
  add             rax, rsi ; прибавляем рсай с предыдущего шага
  adc             rdx, 0 ; адд с флагом переноса
  mov             [rdi], rax
  add             rdi, 8
  mov             rsi, rdx
  dec             rcx
  jnz             .loop

  pop             rcx
  pop             rdi
  pop             rax
  ret

  ; divides long number by a short
  ;    rdi -- address of dividend (long number)
  ;    rbx -- divisor (64-bit unsigned)
  ;    rcx -- length of long number in qwords
  ; result:
  ;    quotient is written to rdi
  ;    rdx -- remainder
  div_long_short:
  push            rdi
  push            rax
  push            rcx

  lea             rdi, [rdi + 8 * rcx - 8] ;
  xor             rdx, rdx

  .loop:
  mov             rax, [rdi]
  div             rbx ; мы тут делим на самом делим число rdxrax. т.е. остаток от деление используется на следующей итерации
  mov             [rdi], rax
  sub             rdi, 8
  dec             rcx
  jnz             .loop

  pop             rcx
  pop             rax
  pop             rdi
  ret

  ; assigns a zero to long number
  ;    rdi -- argument (long number)
  ;    rcx -- length of long number in qwords
  set_zero:
  push            rax
  push            rdi ; присваивает заачению по адресу raxб поэтому он двигаетсяаа
  push            rcx ; становится нулем т.к. счетчик

  xor             rax, rax
  rep stosq ; заполняет rcx раз в поле rdi rax со сдвигом в один ворд

  pop             rcx
  pop             rdi
  pop             rax
  ret

  ; checks if a long number is a zero
  ;    rdi -- argument (long number)
  ;    rcx -- length of long number in qwords
  ; result:
  ;    ZF=1 if zero
  is_zero:
  push            rax
  push            rdi ; указатель на младший разряд выводимого числа
  push            rcx

  xor             rax, rax
  rep scasq ; сравнить rcx раз поле rdi с rax со сдвигом в один ворд

  pop             rcx
  pop             rdi
  pop             rax
  ret

  ; read long number from stdin
  ;    rdi -- location for output (long number)
  ;    rcx -- length of long number in qwords
  read_long:
  push            rcx
  push            rdi

  call            set_zero
  .loop:
  call            read_char
  ; xor              rax, rax ; не нужно
  js              exit
  cmp             rax, 0x0a
  je              .done
  ; cmp             rax, '0'
  ; jb              .invalid_char
  ; cmp             rax, '9'
  ; ja              .invalid_char

  sub             rax, '0'
  mov             rbx, 10
  call            mul_long_short
  call            add_long_short
  jmp             .loop

  .done:
  pop             rdi
  pop             rcx
  ret

  ; .invalid_char:
  ; mov             rsi, invalid_char_msg
  ; mov             rdx, invalid_char_msg_size
  ; call            print_string
  ; call            write_char
  ; mov             al, 0x0a
  ; call            write_char

  .skip_loop:
  call            read_char
  ;or              rax, rax
  js              exit
  cmp             rax, 0x0a
  je              exit
  jmp             .skip_loop

  ; write long number to stdout
  ;    rdi -- argument (long number)
  ;    rcx -- length of long number in qwords
  write_long:
  push            rax
  push            rcx

  mov             rax, 20  ; rax = 128 * 20
  mul             rcx
  mov             rbp, rsp
  sub             rsp, rax ; украли у рсп 20 * 128 памяти

  mov             rsi, rbp

  .loop:
  mov             rbx, 10
  call            div_long_short
  add             rdx, '0'; в rdx лежит младшая цифра числа и мы делаем из нее чар
  dec             rsi
  mov             [rsi], dl ; в рсай поцифренно записываем число
  call            is_zero
  jnz             .loop

  mov             rdx, rbp ; в рбп начало число
  sub             rdx, rsi ; в рсай конец
  call            print_string

  mov             rsp, rbp
  pop             rcx
  pop             rax
  ret

  ; read one char from stdin
  ; result:
  ;    rax == -1 if error occurs
  ;    rax in [0; 255] if OK
  read_char:
  push            rcx
  push            rdi

  sub             rsp, 1
  xor             rax, rax ; тип сискол считывание
  xor             rdi, rdi ; считываем из стдин
  mov             rsi, rsp ; сказали считать в рсп
  mov             rdx, 1 ; сколько считать
  syscall ; поместили в рсай куда считать. поместили мы адрес рсп

  cmp             rax, 1 ; возвращает количество аргументов считанных
  jne             .error
  xor             rax, rax
  mov             al, [rsp] ; самая маленькая самая маленькая часть регистра Rax, 1 байт
  add             rsp, 1 ; двигаем указатель памяти на 1 байт

  pop             rdi
  pop             rcx
  ret
  .error:
  mov             rax, -1
  add             rsp, 1 ; двигаем указатель на место куда считать чтобы в сл раз не просрать что считали
  pop             rdi
  pop             rcx
  ret

  ; write one char to stdout, errors are ignored
  ;    al -- char
  write_char:
  sub             rsp, 1 ; вычли там чет даня про стек даня говорил
  mov             [rsp], al

  mov             rax, 1
  mov             rdi, 1
  mov             rsi, rsp
  mov             rdx, 1 ; сколько выводить
  syscall
  add             rsp, 1
  ret

  exit:
  mov             rax, 60
  xor             rdi, rdi
  syscall

  ; print string to stdout
  ;    rsi -- string
  ;    rdx -- size
  print_string:
  push            rax

  mov             rax, 1
  mov             rdi, 1
  syscall

  pop             rax
  ret


  section         .rodata
  invalid_char_msg:
  db              "Invalid character: "
  invalid_char_msg_size: equ             $ - invalid_char_msg
question from:https://stackoverflow.com/questions/65902924/compiling-asm-file-on-macox-with-nasm

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...