ambiguous operand size or operands invalid for `push'

Тема в разделе "WASM.BEGINNERS", создана пользователем koljakolja, 26 сен 2009.

  1. koljakolja

    koljakolja New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2009
    Сообщения:
    5
    Надо написать простую функцию на ассемблере. В этом я ничего не понимаю.
    Вот файл s.s:

    .intel_syntax noprefix
    .global lol
    .type lol, @function
    lol:
    push ebx
    ret

    Результат:
    $ cc s.s
    s.s: Assembler messages:
    s.s:6: Error: ambiguous operand size or operands invalid for `push'
     
  2. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    Код (Text):
    1. pushl %ebx
     
  3. koljakolja

    koljakolja New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2009
    Сообщения:
    5
    Код (Text):
    1. $ gcc c.c s.s
    2. s.s: Assembler messages:
    3. s.s:6: Error: no such instruction: `pushl %ebx'
     
  4. koljakolja

    koljakolja New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2009
    Сообщения:
    5
    У меня процессор amd64. Это может на что-нибудь влияет?
     
  5. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    угу. надо писать:
    Код (Text):
    1. pushq %rbx
     
  6. koljakolja

    koljakolja New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2009
    Сообщения:
    5
    Код (Text):
    1. .intel_syntax noprefix
    2. .global lol
    3. .type lol, @function
    4.  
    5. lol:
    6.  mov rax, [rsp+4]
    7. ret
    Код (Text):
    1. #include <stdio.h>
    2.  
    3. extern int lol ( int i );
    4.  
    5. //main.c
    6. int main()
    7. {
    8.  printf ( "%d", lol ( 8 ) );
    9.  return 0;
    10. }
    хм, печатает 0. А хочется чтобы 8. Что тут нужно исправить? rsp - адрес возврата, а rsp+1 - адрес первого аргумента? Возвращаемое значение лежит в rax? Или тут всё вообще по-другому? )
     
  7. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    может mov $8(%esp), %rax
     
  8. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    коляколя, вы в курсе, что на amd64 размер указателя равен 8 байтам? То есть адрес возврата в стеке -- это восемь байт. То есть адрес первого аргумента -- это `%rsp + 8'
    Во-вторых. sizeof (int) == 4. То есть если lol имеет указанный заголовок: int lol (int), то выглядеть она должна например так:
    Код (Text):
    1. lol:
    2.     xorq %rax, %rax
    3.     movl $8(%rsp), %eax
    4.     ret
    Из стека берём четыре байта и складываем в %eax.

    ps. кстати. Я не силён во всех этих amd64, не вникал. Но пару раз разглядывал вывод `gcc -S', у меня сложилось устойчивое впечатление, что аргументы передаются в регистрах.
    Читать доки лень, поставил эксперимент:
    Код (Text):
    1. int lol (int i)
    2. {
    3.     return i;
    4. }
    после `gcc -Os -S' превратился в
    Код (Text):
    1. .globl lol
    2.     .type   lol, @function
    3. lol:
    4. .LFB2:
    5.     movl    %edi, %eax
    6.     ret
    7. .LFE2:
    8.     .size   lol, .-lol
    Но это правда linux. Если ты на бзд, то не факт, что там так же.
     
  9. koljakolja

    koljakolja New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2009
    Сообщения:
    5
    Угу, всё понятно, спасибо.