Я не компилировал.
Просто зачем нужно:
    mov    al, 15
    cbw; Это лишняя.
    movsx  bx, ax; А это неправильная команда.
Если можно:
    movsx  ax, BYTE PTR [a]; Вот тут синтаксис tasm не помню.
CBW, если правильно помню, расширяет al до ax, сохраняя знак.
MOVSX уже расширяет байт при копировании до слова, сохраняя знак.
Добавлено через 27 минут и 1 секунду:Потренировался я:
USE32
EXTERN _GetStdHandle@4
EXTERN _WriteConsoleA@20
EXTERN _ExitProcess@4
GLOBAL _start
SECTION .text
start:
    call      setup_console
    mov       eax, title_1
    call      print
; f = (a + b) * (c + d)
; Без проверок!
;a = -15
;b = 70
;c = -25
;d = 35
;f = (-15 + 70) * (-25 + 35) = 55 * 10 = 550 - это должно получиться.
    movsx     ax, BYTE [a]
    movsx     bx, BYTE [b]
    add       ax, bx
    push      ax
    movsx     ax, BYTE [c]
    movsx     bx, BYTE [d]
    add       ax, bx
    pop       bx
    imul      bx
    mov       WORD [f], ax
    cwde
    call      print_num
    mov       eax, title_2
    call      print
push          DWORD 0
call          _ExitProcess@4
; Функция настройки stdout для вывода в консоль.
; ВХОД: без параметров.
; ВЫХОД: записывает значение stdout в глобальную переменную stdout.
; РЕГИСТРЫ: не изменяются.
setup_console:
    push      eax
    push      DWORD -11
    call      _GetStdHandle@4
    mov       [stdout], eax
    pop       eax
    ret
; Функция определения длины строки по завершающему нулю.
; ВХОД: eax - указатель на исследуемую строку.
; ВЫХОД: записывает длину строки в глобальную переменную length.
; РЕГИСТРЫ: не изменяются.
strlen:
    push      eax
    push      esi
    push      edi
    mov       esi, eax
    xor       edi, edi
strlen_loop:
    mov       al, BYTE [esi]
    test      al, al
    jz        strlen_exit
    inc       esi
    inc       edi
    jmp       strlen_loop
strlen_exit:
    mov       DWORD [length], edi
    pop       edi
    pop       esi
    pop       eax
    ret
; Функция выводит строку с завершающим нулём в консоль.
; ВХОД: eax - указатель на строку.
; ВЫХОД: без результатов.
; РЕГИСТРЫ: не изменяются.
print:
    call      strlen
    push      ecx
    push      DWORD 0
    push      DWORD written
    push      DWORD [length]
    push      eax
    push      DWORD [stdout]
    call      _WriteConsoleA@20
    pop       ecx
    ret
; Функция выводит цифру в консоль.
; ВХОД: edx - значение выводимой цифры.
; ВЫХОД: без результатов.
; РЕГИСТРЫ: не изменяются.
print_digit:
    push      eax
    push      ecx
    mov       eax, DWORD line
    add       eax, edx
    push      DWORD 0
    push      DWORD written
    push      DWORD 1
    push      eax
    push      DWORD [stdout]
    call      _WriteConsoleA@20
    pop       ecx
    pop       eax
    ret
; Функция выводит число со знаком в консоль.
; ВХОД: eax - значение числа со знаком.
; ВЫХОД: без результатов.
; РЕГИСТРЫ: не изменяются.
print_num:
    push      eax
    push      ebx
    push      ecx
    push      edx
    xor       ecx, ecx
    mov       ebx, 10
    test      eax, 0x80000000
    jz        print_num_plus
    push      eax
    mov       eax, DWORD minus
    call      print
    pop       eax
    neg       eax
print_num_plus:
    xor       edx, edx
    div       ebx
    push      edx
    inc       ecx
    cmp       eax, 10
    jnc       print_num_plus
    mov       edx, eax
    call      print_digit
    cmp       ecx, 1
    jnz       print_num_loop
    pop       edx
    jmp       print_num_exit
print_num_loop:
    pop       edx
    call      print_digit
    loop      print_num_loop
print_num_exit:
    mov       eax, DWORD line_end
    call      print
    pop       edx
    pop       ecx
    pop       ebx
    pop       eax
    ret    
SECTION .data
a DB -15
b DB 70
c DB -25
d DB 35
f DB 0
title_1 DB "Start.", 0x0A, 0x0D, 0
title_2 DB "Finish.", 0x0A, 0x0D, 0
stdout DD 0
length DD 0
written DD 0
minus DB "- ", 0
line DB "0123456789ABCDEF"
line_end DB 0x0A, 0x0D, 0
Start.
550
Finish.
Для продолжения нажмите любую клавишу . . .
Может где и накосячил, так как бегло набрал.