1. Assembler / Говнокод #21808

    −126

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    [code]
    // межстрочный асм в делфи
    procedure TForm1.Button1Click(Sender: TObject);
    var
      s:string;
    asm
      jmp @code
    @str: db 'Hello, world!', 0
    @code:
      xor ecx, ecx
      xor ebx, ebx
     mov ecx, 0
    @start:
      mov ebx, offset @str
      push 0
      push ebx
      push ebx
      push 0
      call MessageBox
      cmp ecx, 2 
      jne @start
    end;
    [/code]

    Осваиваю межстрочный ассемблер.
    Странно, код зацикливается... Что я делаю не так?

    Запостил: Dr_Stertor, 09 Декабря 2016

    Комментарии (33) RSS

    • Ошибочка, забыл inc. Но в коде он есть, всё равно зацикливает.
      var
        s:string;
      asm
        jmp @code
      @str: db 'Hello, wolrd!', 0
      @code:
        mov ecx,0
      @start:
        push 0
        push offset @str
        push offset @str
        push 0
        call MessageBox
        inc ecx
        cmp ecx, 2
        jne @start
      end;
      Ответить
      • По @start ходит?
        Наверное MessageBox не возвращает 2 (я верно понимаю что это fastcall в WINAPI и там в ecx вертают значение?)

        Блядь, двойка это Cancel.
        А там нет Cancle. Ты же передаешь type 0, а 0 это только OK.
        Единицу переджай туда и жми cance.

        Учись MSDN читать
        https://msdn.microsoft.com/en-us/library/windows/desktop/ms645505(v=vs.85).aspx
        Ответить
        • @Учись MSDN читать
          Что-то ты совсем не в тему написал.
          MessageBox как и другие API возвращают результат в EAX. Не суть.
          Я только хочу дважды показать, на результат не смотрю.
          Ответить
          • и правда
            это stdcall а не fast.

            Ну так тогда MessageBox тебе тупо твой ecx сбрасывает
            Ответить
      • https://en.wikipedia.org/wiki/X86_calling_conventions#stdcall

        Registers EAX, ECX, and EDX are designated for use within the function.
        В общем, согласно stdcall, MessageBox не обязан сохранять значения регистров eax, ecx и edx. Если они для тебя важны - сохраняй их сам.
        Ответить
        • А как это сделать?
          Ответить
          • push ecx перед вызовом напушиванием параметров добавь и pop ecx после возврата из call.
            Ответить
            • было бы смешно если бы MessageBox оставлял ecx = 1 каждый пятый раз. Вот бы чувак долго дебажился)
              Ответить
              • Да соглашения из асма всегда трудно соблюдать... Особенно если их не знаешь ;)
                Ответить
                • Ну вот я был уверен что WINAPI это fastcall, ан нет.

                  Там же еще важно кто стек чистит: колли или коллер. В каком-то асме (masm?) даже были макросы типа PROC где можно было указать конвенцию и не думать ни о чем.

                  Там были только C call и Pascal call.

                  Чуть не забыл: цимес в том, что в 64битном режиме там могут быть другие конвенции совсем)
                  Ответить
                  • я читал, что fastcall - это совместимая хуйна. В делфи, кстати, он зовётся register. Компилятор пытается передавать параметры функции в регистрах, в противном случае, если аргумент не помещается в регистр или число аргументов >3-4 - через стек, что медленнее. Win API - целиком stdcall.
                    Ответить
                    • блин, как хорошо было во времена DOS и BIOS.
                      Прямо в доке было сказано в какие регистры что пихать

                      Один был кол конвеншен: регисторы
                      Ответить
                      • Съешь ещё этих мягких, французских булок mov ax,800h, int 31h, shrd edx, ebx, 16, mov dx,cx да выпей чаю.
                        Ответить
                  • > в 64битном режиме
                    А там соглашения вообще забавные... Наступить на грабли намного проще, чем в x86.
                    Ответить
            • Помогло ) Спс. Но разве в MessageBox не идёт при этом один лишний аргумент?
              Ответить
              • Не, он знает, сколько у него аргументов. Дальше не полезет.

                З.Ы. Напиши этот код на делфи, а потом почитай дизасм. Посмотришь, как компилятор эти проблемы решает.
                Ответить
              • Кстати, у x86 специально, чтобы не думать, какие регистры нужно сохранить, есть инструкция PUSHA, которая запушивает все (ну почти все) регистры общего назначения. А чтобы потом их достать из стека, есть инструкция (барабанная дробь!)... POPA.
                Ответить
                • In the real-address mode, if the ESP or SP register is 1, 3, or 5 when PUSHA/PUSHAD executes: an #SS exception is generated but not delivered (the stack error reported prevents #SS delivery). Next, the processor generates a #DF exception and enters a shutdown state.
                  Ответить
                  • Что ж Вы раньше молчали, Дринкинс? Я бы столько процессоров вырубил...
                    Ответить
    • Ты не на тот форум зашел.
      Ответить
    • показать все, что скрытоEAX проверяй, функция возвращает результат туда.
      Ответить
      • Тред не читай @ сразу отвечай. Въебал тебе минус.
        Ответить
      • Так ты тут регулярно в лужу пердишь оказывается.
        Ответить

    Добавить комментарий