Вычитание десятичных значений (сборка) - PullRequest
4 голосов
/ 28 августа 2010

Как вычесть десятичное значение в сборке .IA32 (linux)

1:       mov edx, 1/2   
         sub ecx, ebx
         sub ecx, edx
         mov bal2, ecx

Я пробовал это, но это как-то пропускает вычитание с десятичной дробью.И если я введу .5 , это выдаст мне ошибку.

error: мусор `.5 'после выражения

Ответы [ 2 ]

4 голосов
/ 29 августа 2010

Как правильно говорит лампочка в своем ответе, вы не можете работать со значениями с плавающей запятой при использовании регистров общего назначения (eax и т. Д.). Вы можете использовать FPU, как подсказывает лампочка, но это довольно утомительно.

В качестве альтернативы - если ваш код не должен работать на древних процессорах - вы можете использовать инструкции SSE для этой задачи, что намного проще. Код, подобный тому, что вы показываете, может выглядеть следующим образом:

.data 
  OneHalf dd 0.5
  bal2 dd ?
.code
  movss xmm0, OneHalf  ; instead of mov edx, 1/2
  subss xmm1, xmm2     ; instead of sub ecx, ebx
  subss xmm1, xmm0     ; instead of sub ecx, edx
  movss bal2, xmm1     ; instead of mov bal2, ecx
2 голосов
/ 28 августа 2010

Код, который вы указали, не может вычесть "десятичное значение". Я предполагаю, что под «десятичным значением» вы действительно подразумеваете значение с плавающей запятой, и в этом случае вы не можете использовать целочисленные арифметические средства, как вы это сделали.

Я настоятельно рекомендую вам загрузить Руководство разработчика программного обеспечения для архитектуры Intel IA-64 ( Mnaul разработчика программного обеспечения для архитектуры Intel IA-64 ) и прочитать разделы, в которых объясняется, как использовать x87 с плавающей запятой объекты. В частности, посмотрите на:

  • Том 1, Раздел 5.2
  • Том 1, глава 8
  • Том 2А, раздел 3.2

В качестве предостережения, мой опыт работы с объектами с плавающей запятой весьма минимален. Тем не менее, я понимаю, что это стековая среда, в которой вы можете загружать (помещать) элемент в стек и затем работать с ним. Команды, на которые я смотрю: FLD, FSUB и FST (все они перечислены в томе 2A).

В качестве примера, вот короткая программа, которая загружает +1 и константу pi в стек с плавающей запятой, затем выполняет операцию pi-1 и выводит результат.

/* floating point subtraction */

    .text
    .globl _main

_main: pushq% rbp movq% rsp,% rbp

    fld1    /* load +1.0 */
    fldpi   /* load pi (3.14159...) */
    fsubp   /* 3.14159 - 1.0, pop result */

    movq    $0x0, %rax
    leave
    ret
...