Other I can't just print a sum in i386 assembler

Here is the program

Code:
segment .data

prompt1: db "Enter a number: ", 0       ; don't forget nul terminator
len1: equ $-prompt1
prompt2: db "Enter another number: ", 0
len2: equ $-prompt2
outmsg1: db "You entered: ", 0
len3: equ $-outmsg1



segment .bss

input1: resd 0
input2: resd 0



segment .text
        global _start
_start:

        mov eax, 4  ; write
        mov ebx, 1  ; stdout
        mov ecx, prompt1
        mov edx, len1 ; len
        int 80h

        mov eax, 3  ; read
        mov ebx, 0  ; stdin
        mov ecx, input1
        ;mov edx, 4  ; len
        int 80h

        mov eax, 4  ; write
        mov ebx, 1  ; stdout
        mov ecx, outmsg1
        mov edx, len3 ; len
        int 80h

        mov eax, 4  ; write
        mov ebx, 1  ; stdout
        mov ecx, input1
        ;mov edx, 4 ; len
        int 80h

        mov eax, 4  ; write
        mov ebx, 1  ; stdout
        mov ecx, prompt2
        mov edx, len2 ; len
        int 80h

        mov eax, 3  ; read
        mov ebx, 0  ; stdin
        mov ecx, input2
        ;mov edx, 4  ; len
        int 80h

        mov eax, 4  ; write
        mov ebx, 1  ; stdout
        mov ecx, outmsg1
        mov edx, len3 ; len
        int 80h

        mov eax, 4  ; write
        mov ebx, 1  ; stdout
        mov ecx, input2
        ;mov edx, 4 ; len
        int 80h

        mov eax, input1     ; eax = dword at input1
        mov ebx, input2     ; eax += dword at input2
        add eax, ebx
        mov ecx, eax
        int 80h

        mov eax, 4  ; write
        mov ebx, 1  ; stdout
        ;mov edx, 1 ; len
        int 80h

        ;Exiting
        mov eax, 1
        mov ebx, 0
        int 80h

Can you help me ?

Thank you
Didier
 
No experience at all with x86 assembly, but I would expect some code converting between (ascii) strings and numbers for that?

Also, if I interpret that correctly, reserving 0 bytes for inputs seems a bit fishy...
 
Homework? This is not a linux or assembly language help group. AFAIK int 80h works (or used to) on Linux. Anyway, in general my advice would be to write a similar C program, compile with the -S flag to create an assembly output and learn from that. Do this on a i386 machine to generate assembly code for that.
 
Anyway, in general my advice would be to write a similar C program, compile with the -S flag to create an assembly output and learn from that.
Of course, only if it isn't homework. Otherwise, calling into libraries would be considered cheating and I guess you don't want to reproduce the whole printf() code in your answer 😈
 

SirDice

Administrator
Staff member
Administrator
Moderator
Code:
mov eax, input1 ; eax = dword at input1 
mov ebx, input2 ; eax += dword at input2
add eax, ebx
input1 and input2 are pointers to the text you entered. You're going to need to convert that text to a number, then you can add those two numbers. All you are doing here is adding two pointers.
 
Hello

To compile the program under freebsd
nasm -f elf32 filename.asm
ld -m elf_i386_fbsd -o filename filename.o
sudo service linux onestart

brandelf -t Linux ./filename

./filename

Thank you
Didier
 
So you're actually looking for help with i386-assembly on Linux. Seems quite off-topic here.

Although this is just a detail in this context, you're clearly missing any distinction between pointers, ascii-encoded bytes and (32bit) numbers. Did you understand any of the answers you got?

edit: in machine language, anything is just bytes (or words consisting of bytes). Still, understanding how to interpret their content, based on what it should be, is really crucial for any assembler programming.
 
Calling convention is different too.
Calling convention is part of the ABI specification. So true but covered by ABI already. :)

If you're sticking to Linux ABI, well OK. To hunt the bugs down gdb is very handy tool. You can single step the program and see the registers each step - that can help you a lot during debugging. I'd say it's a must otherwise you're blind.

If you want to use this as calc you need to follow SirDice advise too. Not only you are adding pointers but those pointers point to a text, not numbers. I can input "asd" "dsa", you won't be able to add them together.

hint: ASCII numbers are from 0x30 - 0x39.
hint2: it's probably good idea to use functions in code as you'll be reusing the code
 
Sometime ago, I've replied to a thread, posting few 'FreeBSD-specific' hello-world style 'working' examples for fasm, as(1), nasm, and "embeded in C".
The only problem is that they run on a FreeBSD x64 machine, and quite frankly the last time I wrote anything for a i386 was with MASM 5.0 for DOS 5.0 and 6.22 — i.e. I can't remember anything! Still, look at the examples. They may give you some hints, maybe not — and that because changing a x64 code to x32 is not just about renaming RAX to EAX.

Here's the link:
 
You are reserving 0 doublewords with resd directive which is not what you want. In BSS all values are initialized to 0.
I'm not going to do the full homework for you but this is part of it. I did only one proof read of this during a boring telco at work so it may have some bugs and/or possibly cleaner code could be used. This program returns sum of digits of both numbers. I've prepped the addition part for you though I didn't use it in code on purpose. Edit: it was just one instruction missing, I put it there. It's up to you to come up with the printing routine though.
Code:
segment .data
    prompt: db "Enter a number: ", 0       ; don't forget nul terminator
    len: equ $-prompt

segment .bss
    nr1:    resd 1
    nr2:    resd 1
    buf:    resb 64

section .text
    global _start
_start:
main:
    call my_atoi
    mov [nr1], eax

    call my_atoi
    mov [nr2], eax

    mov edx, [nr1]
    add eax, edx

    mov ebx,eax
    mov eax,1
    int 0x80

; int my_atoi()
my_atoi:
    push esi
    push edi

    xor edi,edi        ; prep ret val

    ; write(1, prompt, len)
    mov eax, 4
    mov ebx, 1
    lea ecx, [prompt]
    mov edx, len
    int 0x80

    ; read(0, buf, 64)
    mov eax,3
    xor ebx,ebx
    lea ecx, [buf]
    mov edx, 64
    int 0x80

    test eax,eax        ; read() returned 0
    jz .Latoi_end

    cmp eax, -1        ; read() returned err
    je .Latoi_end

    mov edi,eax        ; current read bytes
    xor edx,edx        ; current check pos
    lea esi, [buf]
    cld

.Lcheck1:
    lodsb
    mov ebx,eax
    call isnum        ; isnum(nr)
    test eax, eax
    jz .Latoi_convert    ; not a num anymore

    inc edx
    cmp edx, edi        ; if (edx <= edi)
    jge .Latoi_convert

    cmp edx, 64        ; if (edx <= BUFSZ)
    jge .Latoi_convert
    jmp .Lcheck1

.Latoi_convert:
    xor edi, edi
    mov ecx, edx
    mov ebx, 1

.Latoi_convert.1:
    test ecx, ecx
    jz .Latoi_end
    mov al, [buf+ecx-1]    ; indexing from 0
    movzx eax,al
    sub eax, 0x30
    mul ebx
    add edi, eax

    xor edx,edx
    mov eax, 10
    mul ebx
    mov ebx, eax
    dec ecx
    jmp .Latoi_convert.1

.Latoi_end:
    mov eax, edi
    pop edi
    pop esi
    ret

; isnum(int nr)
isnum:
    xor eax,eax
    cmp bl, 0x30
    jb .Lisnum_end
    cmp bl, 0x39
    jg .Lisnum_end

    inc eax
.Lisnum_end:
    ret
 
+5 ¢
If we need to add two 64-bit unsigned numbers on i386 then we can use adc.
For instance, if the first number sits in edx (high 32 bits) and eax (low 32 bits) and the second number sits in ebx (high 32 bits) and ecx (low 32 bits),
then we can add them something like this:

Code:
add eax, ecx    ; adding low parts
adc edx, ebx   ; adding high parts, take CF into account
 
True. But then printing 64b number in decimal on 32b machine is an interesting problem. If this is homework then I think that problem alone is harder than the original homework.
 
True. But then printing 64b number in decimal on 32b machine is an interesting problem. If this is homework then I think that problem alone is harder than the original homework.
And also parsing the two input numbers! That is why I had suggested writing a C program first. It would also help if the OP wrote down a definition of the problem he is trying to solve. Being able to write a clear problem definition is quite useful. And you can continue to add more notes to it as you learn more about the properties of the solution, without tying yourself up in the coding details (especially if you are new to it).
 
Top