Arithmetic operations in assembly

SYS_EXIT equ 1 SYS_READ equ 3 SYS_WRITE equ 4 STDIN equ 0 STDOUT equ 1 segment .data msg db "Please enter a digit ", 0xA,0xD len equ $- msg segment .bss number1 resb 2 number2 resb 2 result resb 1 result2 resb 1 segment .text msg2 db "Please enter a second digit", 0xA,0xD len2 equ $- msg2 msg3 db "The sum is: " len3 equ $- msg3 msg4 db "The minus is: " len4 equ $- msg4 global _start _start: mov eax, SYS_WRITE ; System write mov ebx, STDOUT ; System output mov ecx, msg ; What to write mov edx, len ; Length to write int 0x80 ; Interupt Kernel mov eax, SYS_READ ; System read mov ebx, STDIN ; mov ecx, number1 mov edx, 2 int 0x80 mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, msg2 mov edx, len2 int 0x80 mov eax, SYS_READ mov ebx, STDIN mov ecx, number2 mov edx, 2 int 0x80 call add add: mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, msg3 mov edx, len3 int 0x80 ;load number1 into eax and subtract '0' to convert from ASCII to decimal mov eax, [number1] sub eax, '0' ; do the same for number2 mov ebx, [number2] sub ebx, '0' ; add eax and ebx, storing the result in eax add eax, ebx ; add '0' to eax to convert the digit from decimal to ASCII add eax, '0' ; store the result in result mov [result], eax ; print the result digit mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, result mov edx, 1 int 0x80 ret minus: mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, msg4 mov edx, len4 int 0x80 ;load number1 into eax and subtract '0' to convert from ASCII to decimal mov eax, [number1] sub eax, '0' ; do the same for number2 mov ebx, [number2] sub ebx, '0' ; add eax and ebx, storing the result in eax sub eax, ebx ; add '0' to eax to convert the digit from decimal to ASCII add eax, '0' ; store the result in result mov [result2], eax ; print the result digit mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, result mov edx, 1 int 0x80 ret mul: ;load number1 into eax and subtract '0' to convert from ASCII to decimal mov al, [number1] sub al, '0' ; do the same for number2 mov bl, [number2] sub bl, '0' ; add eax and ebx, storing the result in eax mul bl ; add '0' to eax to convert the digit from decimal to ASCII add al, '0' ; store the result in result mov [result], al ; print the result digit mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, result mov edx, 1 int 0x80 ret exit: mov eax, SYS_EXIT xor ebx, ebx int 0x80 

The above code is what I have done so far, I tried to add numbers, but the add function seems to be called twice, as shown in the picture below. What I'm trying to do is add, subtract, multiply and divide two numbers. How can I do this, and when I try to add 2 numbers, sometimes it gave me this segmentation error. enter image description here

-2
source share
1 answer

You defined your functions in the middle of the _start block.

Make a one-step code in the debugger and note that after the call add returns, execution continues in the instructions, starting with the add label.

In the end, you will work when you reach ret , i.e. when trying to ret from _start (because the top of the stack is argc , not the address, when the process starts in System V ABI). Or maybe you even made a mistake earlier; you did not publish the output of the debugger, and I did not model it in my head to find out what would happen.

That is why The sum is: ? printed twice.

I think your code will also not be able to handle multi-digit numbers, so you got the ASCII code '0' + 8+9 or something else. See How to print an integer in an assembly-level program without printf in c library? or in a simplified version with two digits. Or just use printf if you dynamically bind libc so that it can call its own init functions.

0
source

Source: https://habr.com/ru/post/1274776/


All Articles