-2

So, I've been trying to learn some assembly and I saw an example of an addition but I don't really understand one thing:

section .text
    global _start       
_start:                     
    mov eax, '3'
    sub eax, '0'
    mov ebx, '4'
    sub ebx, '0'
    add eax, ebx
    add eax, '0'
    mov [sum], eax
    mov ecx, msg
    mov edx, len
    mov ebx, 1
    mov eax, 4
    int 0x80
    mov ecx, sum
    mov edx, 1
    mov ebx, 1
    mov eax, 4
    int 0x80
    mov eax, 1
    int 0x80
section .data
msg db  'The sum is:',0xA, 0xD
len equ $ - msg 
segment .bss
sum resb

I understand all except for the sub eax, '0'

I mean the result should be -7 because when it does sub eax, '0' it inverses the number...

phuclv
  • 37,963
  • 15
  • 156
  • 475
Deketh
  • 3
  • 1
  • 4
  • 5
    Don't post images but code please. – PilouPili Nov 04 '18 at 20:53
  • 1
    what do you think `mov eax,'3'` does? It will set `eax` register to value 51, which is ASCII code for glyph "3" ... and to get binary integer value 3 from that you have to subtract 48 (51-48=3). And `'0'` is that, value 48 (check ASCII table to get the idea how different letters are encoded by 7 bit integers in ASCII encoding). So that code is doing (51-48) + (52-48) + 48 and that is output as ASCII letter.. BTW, the code contains bugs, like `mov [sum],eax` is wrong (it writes the new letter "7" to memory and then it overwrites next 3 bytes with zeroes... it should have been `mov [sum],al` – Ped7g Nov 04 '18 at 21:21
  • 1
    Also `7-0 = 7`, subtracting zero doesn't invert value. Subtracting from zero inverts value (`0-7 = -7`). So your expectations are already wrong on the logic level, even if that `'0'` would be actual zero (it's not, it's 48 or 0x30 or 0b00110000, or whichever formatting you prefer, the original author did prefer "character" quotes formatting in source code, i.e. `'0'` and the assembler will parse that and encode it in binary machine code as 00110000). – Ped7g Nov 04 '18 at 21:24
  • But sub eax, '0' substracts eax to zero and stores it in eax, at least that's what I read – Deketh Nov 05 '18 at 09:29
  • @Deketh no. I'm not sure what you mean by "subtracts eax to zero", I'm not native English speaker, but I think you can either subtract zero **from** eax or eax **from** zero (in math terms result = eax - 0, or result = 0 - eax). The second one would work as "negate" instruction, but that one is not possible on 8086..80586 with integer math, there is no reversed subtraction (maybe there is in the MMX/SSE/AVX/... extended instructions, I don't know those from head). With x87 FPU coprocessor there actually *is* reversed subtraction (`fsub` vs `fsubr`) for FP numbers. And `'0'` is 48 (NOT zero). – Ped7g Nov 05 '18 at 13:38
  • (also there is `neg` instruction for that specialized invert case, but generally, if you have value in `eax` and you want to subtract `eax` from some immediate like 200, you have to put value 200 first into register or memory, and then do `sub , eax` ... there is no x86 instruction doing directly `"sub 200_as_immediate,eax" and store result into eax`. Or you can do `neg eax` `add eax,200` which will produce same result as the non-existent instruction.) – Ped7g Nov 05 '18 at 13:42
  • ah, ok, now I understand, thank you very much. – Deketh Nov 07 '18 at 09:20

1 Answers1

1

... because when it does sub eax, '0' it inverses the num

The subtraction sub eax, '0' converts the character in AL into the corresponding number 0-9. Nothing more.

It should have been written:

sub al, '0'

In the same manner will the instruction add al, '0' convert the number in AL (in the range 0-9) into a character that's ready for outputting.


I mean the result should be -7

If you run the program, you'll see that the output will be a positive 7.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76