Im writing in nasm x86 assembly code that does -_ where the blanks are user input. Now I already have it where it does this, but I need it to read the next line and do it there as well. Im new to assembly, and I don't want to use loops or pointers or anything. Maybe a way with Times? this is my code:
segment .data
newline db 0xA, 0xD
newlinelen equ $-newline
segment .bss
num1 resb 2
num2 resb 2
num3 resb 2
;num4 resb 2
;num5 resb 2
;num6 resb 2
res resb 1
;res2 resb 1
section .text
global main ;must be declared for using gcc
main: ;tell linker entry point
;reading num 1
mov eax, 3
mov ebx, 0
mov ecx, num1
mov edx, 2
int 0x80
;reading num 2
mov eax, 3
mov ebx, 0
mov ecx, num2
mov edx, 2
int 0x80
;reading num 3
mov eax, 3
mov ebx, 0
mov ecx, num3
mov edx, 2
int 0x80
;new line for next equation
mov edx, newline
mov ecx, newlinelen
mov ebx, 1
mov eax, 4
int 0x80
; moving the first number to eax register and second number to ebx
; and subtracting ascii '0' to convert it into a decimal number
mov eax, [num1]
sub eax, '0'
mov ebx, [num2]
sub ebx, '0'
mov ecx, [num3]
sub ecx, '0'
; add ebx to eax
add eax, ebx
; add '0' to to convert the sum from decimal to ASCII
add eax, '0'
; storing the sum in memory location res
mov [res], eax
;subtract ecx from eax
sub eax, ecx
mov [res], eax
; print the sum
mov eax, 4
mov ebx, 1
mov ecx, res
mov edx, 1
int 0x80
exit:
int 0x80
My input with this was 1 2-1 and output was 2, which was right. I don't need to use it on any number above 4, or negative numbers. And I have tried just repeating the whole thing with numbers 4, 5, 6 but it just gives me a blank ascii character as the result, which is the closest I've gotten to a result.
;;new equation?
;reading num 4
mov eax, 3
mov ebx, 0
mov ecx, num4
mov edx, 2
int 0x80
;reading num 5
mov eax, 3
mov ebx, 0
mov ecx, num5
mov edx, 2
int 0x80
;reading num 6
mov eax, 3
mov ebx, 0
mov ecx, num6
mov edx, 2
int 0x80
; moving the first number to eax register and second number to ebx
; and subtracting ascii '0' to convert it into a decimal number
mov eax, [num4]
sub eax, '0'
mov ebx, [num5]
sub ebx, '0'
mov ecx, [num6]
sub ecx, '0'
; add ebx to eax
add eax, ebx
; add '0' to to convert the sum from decimal to ASCII
add eax, '0'
; storing the sum in memory location res
mov [res2], eax
;subtract ecx from eax
sub eax, ecx
mov [res2], eax
; print the sum
mov eax, 4
mov ebx, 1
mov ecx, res2
mov edx, 1
int 0x80
Ive also tried replacing the eax with AL and the other equation with AH but it doesn't work like that which I also don't understand. And then I also tried to make each one byte and put in segment sign resb 1, for the sign, which didn't work. I just want it to read one more line after.
CodePudding user response:
mov edx, newline mov ecx, newlinelen
You've inversed the registers here.
mov eax, [num1] ... mov [res], eax
Everything between these instructions should use the byte-sized registers instead. Use AL
, BL
, and CL
. Currently you're overwriting memory that doesn't belong to the res variable!
; add '0' to to convert the sum from decimal to ASCII add eax, '0'
You should first do the subtraction and then the conversion back to ASCII, followed by storing the character once in the res variable using mov [res], al
.
exit: int 0x80
Your exit lacks the function number in the eax
register!
Is there a way to repeat this one more time?
Even if you don't like it, a loop is the way to go. The times
operator is an assembly-time functionality. You could turn the whole thing into a macro and have it invoked twice, but then you can just as well write it a second time like you've done now.
CodePudding user response:
I just repeated the code instead with adding values 4, 5, and 6 but putting them in higher characters rather than the lower ones. also adding a read garbage character for the new line.
segment .data
newline db 0xA, 0xD
newlinelen equ $-newline
segment .bss
;defining all variables
num1 resb 2
num2 resb 2
num3 resb 2
;variables for next equation
num4 resb 2
num5 resb 2
num6 resb 2
;newlin for garbage character
newlin resb 1
;result 1 and result 2
res resb 1
res2 resb 1
section .text
global main ;must be declared for using gcc
main: ;tell linker entry point
;reading num 1
mov eax, 3
mov ebx, 0
mov ecx, num1
mov edx, 2
int 0x80
;reading num 2
mov eax, 3
mov ebx, 0
mov ecx, num2
mov edx, 2
int 0x80
;reading num 3
mov eax, 3
mov ebx, 0
mov ecx, num3
mov edx, 2
int 0x80
; moving the first number to eax register and second number to ebx
; and subtracting ascii '0' to convert it into a decimal number
;moving variables in lower halfs
mov AL, [num1]
sub AL, '0'
mov BL, [num2]
sub BL, '0'
mov CL, [num3]
sub CL, '0'
; add ebx to eax
add AL, BL
; storing the sum in memory location res
mov [res], AL
;subtract ecx from eax
sub AL, CL
; add '0' to to convert the sum from decimal to ASCII
add AL, '0'
mov [res], AL
; print the sum
mov eax, 4
mov ebx, 1
mov ecx, res
mov edx, 1
int 0x80
;new line for next equation
mov eax, 4
mov ebx, 1
mov ecx, newline
mov edx, newlinelen
int 0x80
;;new equation?
;;skip garbage character
mov eax, 3
mov ebx, 0
mov ecx, newlin
mov edx, 1
int 0x80
;reading num 4
mov eax, 3
mov ebx, 0
mov ecx, num4
mov edx, 2
int 0x80
;reading num 5
mov eax, 3
mov ebx, 0
mov ecx, num5
mov edx, 2
int 0x80
;reading num 6
mov eax, 3
mov ebx, 0
mov ecx, num6
mov edx, 2
int 0x80
; moving the first number to eax register and second number to ebx
; and subtracting ascii '0' to convert it into a decimal number
;moving variables in higher halfs
mov AH, [newlin]
mov BH, [num4]
sub BH, '0'
mov CH, [num5]
sub CH, '0'
mov DH, [num6]
sub DH, '0'
; add ebx to eax
add BH, CH
;subtract ecx from eax
sub BH, DH
; add '0' to to convert the sum from decimal to ASCII
add BH, '0'
;move ah into memory location res 2
mov [res2], BH
; print the sum
mov eax, 4
mov ebx, 1
mov ecx, res2
mov edx, 1
int 0x80
exit:
mov eax, 1
int 0x80