The aim of the program is to take in 3 arguments and an additional argument from a user and find the sum of it.
I have it working so that it finds the sum of the 3 arguments and prints out the sum.
How do I print a string with no arguments and how do I take input from the user and print that input?
includelib legacy_stdio_definitions.lib
extrn printf:near, scanf:near
.data ; Data section
istr db 'Please enter an integer: '
stri byte '%lld', 0AH, 00
ostr byte 'The sum of proc. and user inputs (%lld, %lld, %lld, %lld): %lld', 0AH, 00
.code ; Code section
public use_scanf ; int use_scanf(long long a, long long b, long long c)
use_scanf: ; {
mov rax, 0 ; sum = 0;
add rax, rcx ; sum += a;
add rax, rdx ; sum += b;
add rax, r8 ; sum += c;
; printf('Please enter an integer');
; scanf();
; printf('%lld', &inp_int);
mov r9, 3 ; temp inp_int
add rax, r9 ; sum += inp_int;
push rbx ; save reg rbx to make space
mov rbx, rax ; save sum in rbx
push rax ; sum.push
push rax ; sum.push
push r9 ; usrinput.push
sub rsp, 32 ; allocate shadow space
mov r9, r8 ; arg3 = c;
mov r8, rdx ; arg2 = b;
mov rdx, rcx ; arg1 = a
lea rcx, ostr ; arg0 = ostr;
call printf ; printf(ostr);
add rsp, 56 ; clear shadow space and vars from stack
mov rax, rbx ; retVal = sum
pop rbx ; return rbx to previous value
ret ; return retVal}
edit: output from console
Please enter an integer: 2
use_scanf_spill4 equ 12 * 8 ; The slots above return address that are
The sum of proc. and user inputs (1, 2, 3, 1002523588520): 1002523588526
use_scanf(1,2,3) = 73 ERROR: should be 7018134685179969542
Please enter an integer: 2
The sum of proc. and user inputs (-3, 2, -2, 1002523588520): 1002523588517
use_scanf(-3,2,-2) = 75 ERROR: should be 7018134685179969533
Please enter an integer: 3
The sum of proc. and user inputs (4, 3, -4, 1002523588520): 1002523588523
use_scanf(4,3,-4) = 74 ERROR: should be 7018134685179969539
Please enter an integer: -3
The sum of proc. and user inputs (-3, -3, -4, 1002523588520): 1002523588510
use_scanf(-3,-3,-4) = 76 ERROR: should be 7018134685179969526
The following is the cpp file to test it.
void check(const char *s, _int64 v, _int64 expected) {
std::cout << s << " = " << v;
if (v == expected) {
std::cout << " OK";
}
else {
std::cout << " ERROR: should be " << expected;
}
std::cout << "\n";
}
_int64 sum_scanf;
_int64 sum_check;
sum_scanf = use_scanf(1, 2, 3);
sum_check = 1 + 2 + 3 + inp_int;
check("use_scanf(1,2,3)", sum_scanf, sum_check);
std::cout << "\n";
sum_scanf = use_scanf(-3, 2, -2);
sum_check = -3 + 2 - 2 + inp_int;
check("use_scanf(-3,2,-2)", sum_scanf, sum_check);
std::cout << "\n";
sum_scanf = use_scanf(4, 3, -4);
sum_check = 4 + 3 - 4 + inp_int;
check("use_scanf(4,3,-4)", sum_scanf, sum_check);
std::cout << "\n";
sum_scanf = use_scanf(-3, -3, -4);
sum_check = -3 - 3 - 4 + inp_int;
check("use_scanf(-3,-3,-4)", sum_scanf, sum_check);
You have calling convention problems. First off, the stack depth divided by 8 must be even. Second off, you do not use push and pop except in the prologue and epilogue.
I'm guessing you started with a basic C implementation, disassembled that, and started editing. The compiler is pulling some advanced tricks here that you're better off avoiding at this early stage. So off to rewriting we go.
I didn't try to optimize anything.
;Take your globals from above -- you will need
use_scanf_spill4 equ 12 * 8 ; The slots above return address that are
use_scanf_spill3 equ 11 * 8 ; for spilling arguments. In theory you can
use_scanf_spill2 equ 10 * 8 ; use them for something else but I didn't.
use_scanf_spill1 equ 9 * 8
use_scanf_space equ 7 * 8 ; it holds return addess -- don't clobber
use_scanf_sum equ 6 * 8
use_scanf_input equ 5 * 8
use_scanf_arg6 equ 5 * 8 ; same as use_scanf_input, but only 1 is used at a time
use_scanf_arg5 equ1 4 * 8
; 0, 1, 2, 3 are argument zone
use_scanf:
; Allocate stack space
; this function doesn't use any non-call-clobbered registers
sub rsp, use_scanf_space
; spill input since we need it later
mov [rsp + use_scanf_spill1], rcx
mov [rsp + use_scanf_spill2], rdx
mov [rsp + use_scanf_spill3], r8
mov [rsp + use_scanf_spill4], r9
; Add arguments together and stash
add rcx, rdx
add rcx, r8
mov [rsp + use_scanf_sum], rcx
; print the promot
lea rcx, istr
call printf
; call scanf
lea rcx, [stri]
; Can't take the address of a register so we give it a memory slot
lea rdx, [rsp + use_scanf_input]
call scanf
; sum the values
mov rdx, [rsp + use_scanf_sum]
mov rax, [rsp + use_scanf_input]
add rax, rdx
; print out the arguments and total
; using rcx as scratch -- will clobber later
mov rdx, [rsp + use_scanf_spill1]
mov r8, [rsp + use_scanf_spill2]
mov r9, [rsp + use_scanf_spill3]
mov rcx, [rsp + use_scanf_input]
mov [rsp + use_scanf_arg5], rcx
mov [rsp + use_scanf_arg6], rax
lea rcx, [ostr]
call printf
; now leave
add rsp, use_scanf_space
ret
Related
I want to call a function that will perform upper to lower case conversion to a user typed string, preserving the especial characters. This part works, but only for the first 4 characters, everything after that just gets truncated. I believe it is because I have defined the parameters as DWORD:
I have tried using PAGE, PARA and BYTE. The first two don't work and with byte says type missmatch.
upperToLower proc, source:dword, auxtarget:dword
mov eax, source ;Point to string
mov ebx, auxtarget ; point to destination
L1:
mov dl, [eax] ; Get a character from buffer
cmp byte ptr [eax], 0 ; End of string? (not counters)
je printString ; if true, jump to printString
cmp dl, 65 ; 65 == 'A'
jl notUpper ; if less, it's not uppercase
cmp dl, 90 ; 90 == 'Z'
jg notUpper ; if greater, it's not uppercase
xor dl, 100000b ; XOR to change upper to lower
mov [ebx], dl ; add char to target
inc eax ; Move counter up
inc ebx ; move counter up
jmp L1 ; loop
notUpper: ; not uppercase
mov [ebx], dl ; copy the letter
inc eax ;next letter
inc ebx
jmp L1
printString:
invoke WriteConsoleA, consoleOutHandle, auxtarget, sizeof auxtarget, bytesWritten, 0
ret
upperToLower endp
The PROTO:
upperToLower PROTO,
source: dword,
auxtarget: dword
Invoke:
invoke upperToLower, offset buffer, offset target
The buffer parameter is: buffer db 128 DUP(?)
How can I get printed the whole string, and not just the first 4 characters?
Why are only 4 characters being printed? You write the string to the console with:
invoke WriteConsoleA, consoleOutHandle, auxtarget, sizeof auxtarget, bytesWritten, 0
The sizeof auxtarget parameter is the size of auxtarget which is a DWORD (4 bytes) thus you are asking to only print 4 bytes. You need to pass the length of the string. You can easily do so by taking the ending address in EAX and subtracting the source pointer from it. The result would be the length of the string you traversed.
Modify the code to be:
printString:
sub eax, source
invoke WriteConsoleA, consoleOutHandle, auxtarget, eax, bytesWritten, 0
A version of your code that follows the C call convention, uses both a source and destination buffer, tests for the pointers to make sure they aren't NULL, does the conversion using a similar method described by Peter Cordes is as follows:
upperToLower proc uses edi esi, source:dword, dest:dword
; uses ESI EDI is used to tell assembler we are clobbering two of
; the cdecl calling convetions non-volatile registers. See:
; https://en.wikipedia.org/wiki/X86_calling_conventions#cdecl
mov esi, source ; ESI = Pointer to string
test esi, esi ; Is source a NULL pointer?
jz done ; If it is then we are done
mov edi, dest ; EDI = Pointer to string
test edi, edi ; Is dest a NULL pointer?
jz done ; If it is then we are done
xor edx, edx ; EDX = 0 = current character index into the strings
jmp getnextchar ; Jump into loop at point of getting next character
charloop:
lea ecx, [eax - 'A'] ; cl = al-'A', and we do not care about the rest
; of the register
cmp cl, 25 ; if(c >= 'A' && c <= 'Z') c += 0x20;
lea ecx, [eax + 20h] ; without affecting flags
cmovna eax, ecx ; take the +0x20 version if it was in the
; uppercase range to start with
mov [edi + edx], al ; Update character in destination string
inc edx ; Go to next character
getnextchar:
movzx eax, byte ptr [esi + edx]
; mov al, [esi + edx] leaving high garbage in EAX is ok
; too, but this avoids a partial-register stall
; when doing the mov+sub
; in one instruction with LEA
test eax, eax ; Is the character NUL(0) terminator?
jnz charloop ; If not go back and process character
printString:
; EDI = source, EDX = length of string
invoke WriteConsoleA, consoleOutHandle, edi, edx, bytesWritten, 0
mov edx, sizeof buffer
done:
ret
upperToLower endp
A version that takes one parameter and changes the source string to upper case could be done this way:
upperToLower proc, source:dword
mov edx, source ; EDX = Pointer to string
test edx, edx ; Is it a NULL pointer?
jz done ; If it is then we are done
jmp getnextchar ; Jump into loop at point of getting next character
charloop:
lea ecx, [eax - 'A'] ; cl = al-'A', and we do not care about the rest
; of the register
cmp cl, 25 ; if(c >= 'A' && c <= 'Z') c += 0x20;
lea ecx, [eax + 20h] ; without affecting flags
cmovna eax, ecx ; take the +0x20 version if it was in the
; uppercase range to start with
mov [edx], al ; Update character in string
inc edx ; Go to next character
getnextchar:
movzx eax, byte ptr [edx] ; mov al, [edx] leaving high garbage in EAX is ok, too,
; but this avoids a partial-register stall
; when doing the mov+sub in one instruction with LEA
test eax, eax ; Is the character NUL(0) terminator?
jnz charloop ; If not go back and process character
printString:
sub edx, source ; EDX-source=length
invoke WriteConsoleA, consoleOutHandle, source, edx, bytesWritten, 0
done:
ret
upperToLower endp
Observations
A generic upperToLower function that does the string conversion would normally not do the printing itself. You'd normally call upperToLower to do the conversion only, then you'd output the string to the display in a separate call.
I am trying to learn assembly and am starting to understand the basics and I found a part of this code online and have been messing with it. Here is the code:
%include "io.inc"
prompt1 db "Enter a number: ", 0
prompt2 db "Enter another number: ", 0
outmsg1 db "You entered ", 0
outmsg2 db " and ", 0
outmsg3 db ", the sum of these is ", 0
segment .bss
input1 resd 1
input2 resd 1
segment .text
global _asm_main
_asm_main:
mov ebp, esp; for correct debugging
enter 0,0 ; setup routine
pusha
mov eax, prompt1 ; print out prompt
call print_string
call read_int ; read integer
mov [input1], eax ; store into input1
mov eax, prompt2 ; print out prompt
call print_string
call read_int ; read integer
mov [input2], eax ; store into input2
mov eax, [input1] ; eax = dword at input1
add eax, [input2] ; eax += dword at input2
mov ebx, eax ; ebx = eax
dump_regs 1 ; print out register values
dump_mem 2, outmsg1, 1 ; print out memory
mov eax, outmsg1
call print_string ; print out first message
mov eax, [input1]
call print_int ; print out input1
mov eax, outmsg2
call print_string ; print out second message
mov eax, [input2]
call print_int ; print out input2
mov eax, outmsg3
call print_string ; print out third message
mov eax, ebx
call print_int ; print out sum (ebx)
call print_nl ; print new-line
popa
mov eax, 0 ; return back to C
leave
ret
I uses SASM compiler and these are the errors:
C:\Users\*my user name*\AppData\Local\Temp\SASM\program.asm:27: error: parser: instruction expected
C:\Users\*my user name*\AppData\Local\Temp\SASM\program.asm:28: error: parser: instruction expected
gcc.exe: error: C:\Users\*my user name*\AppData\Local\Temp\SASM\program.o: No such file or directory
I still do not know assembly well enough to debug this and was wondering if any of you could help me out.
[EDIT] lines 27 and 28 are as follows:
dump_regs 1 ; print out register values
dump_mem 2, outmsg1, 1 ; print out memory
I need help with Assembly code which I just started learning.
.intel_syntax noprefix;
.text;
.globl main;
main:
mov eax, 3;
mov ebx, 0;
push eax;
push ebx;
call f;
add esp, 8;
push eax;
mov eax, offset message;
push eax;
call printf
add esp,8;
mov eax,0;
ret;
f:
mov eax, [esp+8];
mov ebx, [esp+4];
cmp eax,3;
jge ety2;
cmp eax,2;
je ety1;
cmp eax,0;
je ety1;
cmp eax,1;
je ety3;
ety3:
mov eax,0;
ret;
ety1:
mov eax,1;
ret;
ety2:
xor ebx,ebx;
dec eax;
push eax;
push ebx;
call f;
add esp,8;
add ebx,[esp+4];
add ebx,eax;
mov eax,[esp+8];
dec eax;
dec eax;
push eax;
push ebx;
call f;
add esp,8;
add ebx,[esp+4];
add ebx,eax;
add ebx,eax;
mov eax,[esp+8];
dec eax;
dec eax;
dec eax;
push eax;
push ebx;
call f;
add esp,8;
add ebx,[esp+4];
sub ebx,eax;
mov eax,[esp+8];
mov eax,ebx;
ret;
.data;
message:
.asciz "Result=%i\n";
.att_syntax prefix;
In main function 'eax' register is used as a 'n' parameter for function that:
for n=0 or n=2 returns 1;
for n=1 returns 0;
for n>=3 returns f(n-1)+(2*f(n-2))-f(n-3);
So for n=3 function returns 0, n=4 returns 2, n=5 returns 1, n=6 returns 5 e.t.c.
The recursion is pretty problematic, for values < 5 fuction works fine, but for 6, 7 e.t.c. function returns tremendously high or low (negative) values.
I've been working on it for +10 hours, and I can't manage to make it work
property. What am I doing wrong?
It is required to use "PUSH" and "[esp+4]", "add esp,4;" and other simple instructions that are already in the code.
Program is compiled under -m32 command parameter(gcc -Wall funcas.s -m32 -o test).
I wrote down the same code in C to show what i'm trying to achieve
#include <stdio.h>
#include <stdlib.h>
int funkcja(int n)
{
if(n>=3)
{
return (funkcja(n-1)+(2*funkcja(n-2))-funkcja(n-3));
}
else
{
if(n==2)return 1;
if(n==1)return 0;
if(n==0)return 1;
}
return -1;
}
int main()
{
int a=6;
printf("%d\n", funkcja(a));
return 0;
}
The problem is that the code keeps accumulating all of the results. Change f to only use one parameter. Example Microsoft type assembler code. In both f() and main(), n is stored on the stack.
.model flat,c
; ...
.data
fmt db '%d',00ah,000h
.code
extern printf:proc
public main
f proc ;int f(int n)
mov eax, [esp+4]
cmp eax,3
jge f2
cmp eax,2
je f1
cmp eax,1
je f0
cmp eax,0
je f1
mov eax,-1
ret
f0: mov eax,0
ret
f1: mov eax,1
ret
f2: push ebx ;save ebx
dec eax ;eax = n-1
push eax ;[esp] = n-1
call f ;eax = f(n-1)
mov ebx,eax ;ebx = f(n-1)
dec dword ptr [esp] ;[esp] = n-2
call f ;eax = f(n-2)
add eax,eax ;eax = 2*f(n-2)
add ebx,eax ;ebx = f(n-1) + 2*f(n-2)
dec dword ptr [esp] ;[esp] = n-3
call f ;eax = f(n-3)
add esp,4 ;restore esp
sub ebx,eax ;ebx = f(n-1) + 2*f(n-2) - f(n-3)
mov eax,ebx ;eax = f(n-1) + 2*f(n-2) - f(n-3)
pop ebx ;restore ebx
ret
f endp
main proc near
push dword ptr 0 ;[esp] = n
main0: call f
push eax
push offset fmt
call printf
add esp,8
inc dword ptr [esp]
cmp dword ptr [esp],20
jl main0
add esp,4
xor eax,eax
ret
main endp
I don't understand your action with EBX and the second argument on the stack.
Let's start from scratch. A recursive function is a function as well. When you call it you have to preserve registers which can be altered by the function and you need unaltered after the function return. The function calls itself three times with different n and operates with the different results. While you've got n on the stack for arbitrary recovery, you have to preserve the results. It becomes more clear when you split return (funkcja(n-1)+(2*funkcja(n-2))-funkcja(n-3)); into
int result = 0;
result += funkcja(n-1);
result += ( 2 * funkcja(n-2) );
result -= funkcja(n-3);
return result;
result is a so called local variable. It's only needed for this run of the function and will lost with the function return. A local variable is usually stored on the stack. You don't need to build a stackframe with prolog and epilog, a simple push/pop combination will do it as well.
# f(n) = f(n-1) + (2*f(n-2)) - f(n-3)
# 0 1
# 1 0
# 2 1
# 3 0 1 + 0 - 1
# 4 2 0 + 2 - 0
# 5 1 2 + 0 - 1
# 6 5 1 + 4 - 0
# 7 5 5 + 2 - 2
# 8 14 5 + 10 - 1
# 9 19 14 + 10 - 5
.intel_syntax noprefix
.text
.globl main
main:
mov eax, 9
push eax
call funkcja
add esp, 4
push eax
mov eax, offset message
push eax
call printf
add esp,8
mov eax,0
ret
funkcja:
mov eax, [esp+4]
cmp eax,3
jge 3f
2:
cmp eax,2
jne 0f
mov eax, 1
ret
0:
cmp eax,0
jne 1f
mov eax, 1
ret
1:
xor eax, eax
ret
3:
push 0 # Result = 0
# 1. Call
mov eax, [esp+8] # +8: retrieve n behind push and return address
sub eax, 1
push eax
call funkcja
add esp, 4
add [esp], eax # Result += EAX
# 2. Call
mov eax, [esp+8] # +8: retrieve n behind push and return address
sub eax, 2
push eax
call funkcja
add esp, 4
add eax, eax
add [esp], eax # Result += EAX
# 3. Call
mov eax, [esp+8] # +8: retrieve n behind push and return address
sub eax, 3
push eax
call funkcja
add esp, 4
sub [esp], eax # Result -= EAX
pop eax # Return EAX = Result
ret
.data;
message: .asciz "Result=%i\n"
.att_syntax prefix
I have this assembly program and I want diagonal output of this program but I dont know how to put tabspace in assembly.
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov edx, len ;message length
mov ecx, msg ;message to write
mov ebx, 1 ;file descriptor (stdout)
mov eax, 4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax, 1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
msg db 'Y',10,'O',10,'U',10,'S',10,'U',10,'F' ;our dear string
len equ $ - msg ;length of our dear string
Output of my program is:
Y
O
U
S
U
F
Output should like this:
Y
O
U
S
U
F
Is there any other way to write this program and get this output?
is there an other way to do this
Of course there is! You can do it anyway that you want! Since you say you are using Windows, but are using Linux Interrupts, this code is OS Neutral (meaning it will work on Windows or Linux)
extern exit, printf, malloc, free
global main
section .data
szText db "Gunner Diagonally!!"
Text_Len equ $ - szText
fmtstr db "%s", 10, 0
section .text
main:
push Text_Len
push szText
call PrintDiagonal
call exit
;~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;~ PrintDiagonal - Prints text to terminal diagonally
;~ In: esp + 4 = address of text to print
;~ esp + 8 = length of string to print
;~ Returns - Nothing
;~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PrintDiagonal:
%define Text_ dword [ebp + 8]
%define TextLen_ dword [ebp + 12]
%define _Buffer dword [ebp - 4]
%define _SpaceCount dword [ebp - 8]
%define _CurLine dword [ebp - 12]
push ebp
mov ebp, esp
sub esp, 4 * 3
mov eax, TextLen_
add eax, eax
push eax
call malloc
add esp, 4 * 1
mov _Buffer, eax
mov _SpaceCount, 1
mov _CurLine, 1
mov esi, Text_
.NextLine:
mov edi, _Buffer
mov edx, _SpaceCount
dec edx
jz .SpaceDone
.SpaceStart:
mov ecx, _SpaceCount
dec ecx
.FillSpaces:
mov byte [edi], 32
inc edi
dec ecx
jnz .FillSpaces
.SpaceDone:
mov al, byte [esi]
mov byte [edi], al
mov byte [edi + 1], 0
push _Buffer
push fmtstr
call printf
add esp, 4 * 2
inc esi
add _SpaceCount, 2
mov edx, TextLen_
inc _CurLine
cmp _CurLine, edx
jng .NextLine
push _Buffer
call free
add esp, 4 * 1
leave
ret 4 * 2
There is no error checking, of course you would add your own.
We take the string and add the correct spaces in a loop then print.
You could put in your msg
msg db 'Y',10,9,'O',10,9,9,'U',10,9,9,9,'S',10,9,9,9,9,'U',10,9,9,9,9,9,'F' ;our dear string
9 is ascii for tab.
Only Windows (because of DOS legacy) has separated CR (carriage return) that moves the carriage at X position 0, and LF (line feed) that moves one line down without changing the carriage X position.
In Linux LF only is used and it do both: moves the carriage down and left to 0.
In order to have the same diagonal output in Linux, you should cheat a little:
; replace dots with spaces.
msg db 'Y',10,'.O',10,'..U',10,'...S',10,'....U',10,'.....F'
I was asked to create a bubble sort program in NASM Ubuntu. Here's the code:
section .data
i db 0 ; Value to be incremented
question db 'Enter a number: ' ; Prompt
questionLen equ $-question
newLine db 10, 10, 0 ; New blank line
newLineLen equ $-newLine
section .bss
num resb 5 ; Array of size 5
counter resb 1 ; Value to be incremented
counter2 resb 1 ; Value to be incremented
temp resb 1
temp2 resb 1
section .text
global _start
_start:
mov esi, 0
getInput:
mov eax, 4
mov ebx, 1
mov ecx, question ; Prints the question
mov edx, questionLen
int 80h
add byte[i], 30h ; I'll retain this expression, since the program experienced an error
; when this expression is deleted
sub byte[i], 30h ; Converts the increment value to integer
mov eax, 3
mov ebx, 0
lea ecx, [num + esi] ; Element of the array
mov edx, 2
int 80h
inc esi
inc byte[i]
cmp byte[i], 5 ; As long as the array hasn't reached the size of 5,
jl getInput ; the program continues to ask input from the user
mov esi, 0
mov byte[i], 0
mov edi, 0 ; Index of the array
bubble_sort:
mov byte[counter], 0
mov byte[counter2], 0
begin_for_1:
mov al, 0
mov al, [counter] ; Acts as the outer for loop
cmp al, 5
jg printArray ; Prints the sorted list when the array size has reached 5
begin_for_2:
mov edi, [counter2] ; Acts as the inner for loop
cmp edi, 4
jg end_for_2
mov bl, 0 ; Acts as the if statement
mov cl, 0
mov bl, [num + edi]
mov cl, [num + edi + 1]
mov byte[temp], cl ; This is the same as if(a[j] > a[j + 1]){...}
cmp bl, [temp]
jg bubbleSortSwap
return:
inc edi ; Same as j++
jmp begin_for_2 ; Goes out of the inner for loop
end_for_2:
inc byte[counter] ; Same as i++
jmp begin_for_1 ; Goes out of the outer for loop
bubbleSortSwap:
mov [num + edi + 1], bl
mov [num + edi], cl ; The set of statements is the same as swap(&a[j], &a[j + 1]);
jmp return
printArray:
mov eax, 4
mov ebx, 1
mov ecx, [num + esi] ; Prints one element at a time
mov edx, 1
int 80h
inc esi
inc byte[i]
cmp byte[i], 5
jl printArray ; As long as the array size hasn't reached 5, printing continues
mov eax, 4
mov ebx, 1
mov ecx, newLine ; Displays a new blank line after the array
mov edx, newLineLen
int 80h
mov eax, 1 ; Exits the program
mov ebx, 0
int 80h
But the only problem is, it cannot print the rest of the iterations, because it only prints the 1st iteration like this:
Enter a number: 7
Enter a number: 1
Enter a number: 4
Enter a number: 3
Enter a number: 5
17435
What I want to output is the array input and the final output, from the 1st iteration up to the last.
Naw... he just needs some stuff sorted! :)
Doesn't print any output at all for me, as posted. Problem is you're putting "[contents]" in ecx - you want address - you do it right in the input routine.
You can get by with fewer variables - use esi and/or edi as both the "count" and the "index". If you use variables, make sure the size of the variable matches the size of the register you're moving it in/out of! ("mov edi, [counter2]" isn't doing what you want) Courage! If it wuz easy, everybody'd be doing it.
Best,
Frank