среда, 20 ноября 2013 г.

Маленько программирования

Немного о System V и x86_64
   Да, он на порядки эффективнее, чем аналогичная архитектура
   от MS. И да, я его уважаю. И он не только лине и BSD перепал,
   но еще и маку достался. И все бы хорошо...

Вы пробовали читать документацию, аккуратно, по пунктам?
   В System V x86_64 ABI почти всегда для передачи аргументов
   используются регистры. И для возврата их тоже не мало
   используется. Больше чем на x86 точно. И больше чем в AMD64
   MS варианте. Не сложно заметить из документации, что числа
   с плавающей точкой передаются посредством типичных для них
   регистров. Например st0, или xmm0 из SSE. Хорошо. Отлично.
   И все бы ничего, если бы где-то, на две страницы выше, совсем
   в другой теме документации не было написано, что в регистр rax
   не просто временный, но туда еще лезет количество передающихся
   через SSE значений...
Сколько времени долнжо уйти, чтобы догадаться, где проблема
в следующей ситуации?..
   ; Get necessary data
   invoke _scanf,'%lg %c %lg',[a]#,[operation]#,[b]#
   
   invoke _printf, `Input: %.17lg %c %.17lg\n`, [a]!, [operation], [b]!
   -- Выводит правильный результат
   ; Get necessary data
   invoke _scanf,'%lg %c %lg',[a]#,[operation]#,[b]#
   
   invoke _printf, `Input: %.17lg %c %.17lg\n`, [a]!, [operation], [b]!
   mov al,[operation]
   sub al,42
   jz .do_mlt
   sub al,1
   jz .do_sum
   sub al,2
   jz .do_sub
   sub al,2
   jz .do_div
   
   invoke _puts, 'Error: unsuppoted operation'
   jmp .exit

   .do_mlt:
      invoke float_mlt,[a]!,[b]!
      jmp .print
   .do_sum:
      invoke float_add,[a]!,[b]!
      jmp .print
   .do_sub:
      invoke float_sub,[a]!,[b]!
      jmp .print
   .do_div:
      invoke float_div,[a]!,[b]!

   .print:
      movsd [a],xmm0
      invoke _printf, `Result: %.17lg\n`, [a]!
    -- Тоже ок
   ; Get necessary data
   invoke _scanf,'%lg %c %lg',[a]#,[operation]#,[b]#
   
   ;invoke _printf, `Input: %.17lg %c %.17lg\n`, [a]!, [operation], [b]!
   mov al,[operation]
   sub al,42
   jz .do_mlt
   sub al,1
   jz .do_sum
   sub al,2
   jz .do_sub
   sub al,2
   jz .do_div
   
   invoke _puts, 'Error: unsuppoted operation'
   jmp .exit

   .do_mlt:
      invoke float_mlt,[a]!,[b]!
      jmp .print
   .do_sum:
      invoke float_add,[a]!,[b]!
      jmp .print
   .do_sub:
      invoke float_sub,[a]!,[b]!
      jmp .print
   .do_div:
      invoke float_div,[a]!,[b]!

   .print:
      movsd [a],xmm0
      invoke _printf, `Result: %.17lg\n`, [a]!
   -- ХРЕНЬ!

   Просто уже от нефиг делать, исключил все. Оставил только
   switch. ХРЕНЬ!
   Исключил switch -- ок.
   xor al,al
   -- И вот она родимая -- ХРЕНЬ!
   
Ну как-то так.

Вывод: Товарищи. То, что писалось для автоматизированных
   программ (в данном случае -- компиляторов), НЕ СЛЕДУЕТ
   тыкать ручками. Программа все равно лучше знает --
   ее ведь закодил тот же упоротый человечишко, что придумал
   эту хрень.
Вывод 2: И нефиг вообще делать такие неожиданности -- rax,
   да от него зависят аргументы! 20 с лишним лет он никому
   был не нужен, а тут нате вам...
Ну и злой я, на убитые суммарно часов 10, не меньше =(

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

Отправить комментарий