I am writing a MASM program using the Irvine32 Library from my textbook. I want to line up my printed columns, but I couldn't finds anything on how to terminate a string with a tab-stop, /t for C/C++, so I made a procedure that determines how many decimal places the number has and assigns the spacer string variable accordingly.
My issue is when trying to assign spacer a new string, I get assembling errors. I have tried
mov spacer, "New String",0
and
mov spacer, "New String"
as well as assigning "New String" to a variable and assigning spacer that variable as well as that variables OFFSET. I now have it where the variables OFFSET is moved into edx but I can't move edx into the other variable.
I would greatly appreciate the help and any information to help be better understand why this doesn't work in assembly or MASM in particular. Thanks
Procedure in question:
; Define the spacer based on the places in x
spacer_choice proc
cmp x, 10
JB SC1
cmp x, 100
JB SC2
mov edx, OFFSET hundo_spacer
JMP SC3
SC1:
mov edx, OFFSET one_spacer
JMP SC3
SC2:
mov edx, OFFSET ten_spacer
JMP SC3
SC3:
mov spacer, OFFSET edx
RET
spacer_choice endp
Output:
1>------ Build started: Project: MASM4, Configuration: Debug Win32 ------
1> Assembling composite.asm...
1>composite.asm(209): error A2032: invalid use of register
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations\masm.targets(50,5): error MSB3721: The command "ml.exe /c /nologo /Sg /Zi /Fo"Debug\composite.obj" /Fl"MASM4.lst" /I "c:\Irvine" /W3 /errorReport:prompt /Tacomposite.asm" exited with code 1.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Full Code:
INCLUDE Irvine32.inc
.data
; ----- GLOBALS
n_comps DWORD ?
; ----- INTRO VALUES
; Greeting the User
title_prompt BYTE "Welcome to Prog. 4, my name is Zach", 10, 13, 0
name_prompt BYTE "What should I call you?: ", 0
username BYTE 21 DUP(0)
user_greet BYTE "Hello, ", 0
; Instructing the User
one_instruct BYTE "We are going to calculate all the composite numbers from 1 to n.", 10, 13, 0
two_instruct BYTE "N is the number you enter. That number has to be an integer,", 10, 13, 0
three_instruct BYTE "and in the range of 1 to 400.", 10, 13, 0
; ----- INPUT VALUES
; Prompts
int_prompt BYTE "How many composite numbers do you want to display? 1 to 400: ", 0
bad_prompt BYTE "Your Input was bad, try again", 10, 13, 0
; Constants
MAX_VAL = 400
MIN_VAL = 1
; ----- CALCULATE
x DWORD ?
spacer BYTE ?
count DWORD ?
; ----- SPACER_CHOICE
one_spacer BYTE ", ", 0
ten_spacer BYTE ", ", 0
hundo_spacer BYTE ", ", 0
; ----- OUTRO
farewell BYTE "Hope you've had fun printing composites! Goodbye, ", 0
.code
main proc
call intro
call input
call calculate
call outro
invoke ExitProcess, 0
main endp
; Greet the User and get their name
intro proc
; Greet
mov edx, OFFSET title_prompt
call WriteString
; Prompt for username
mov edx, OFFSET name_prompt
call WriteString
mov edx, OFFSET username
mov ecx, SIZEOF username
call ReadString
mov edx, OFFSET user_greet
call WriteString
mov edx, OFFSET username
call WriteString
call Crlf
; Intruct the User
mov edx, OFFSET one_instruct
call WriteString
mov edx, OFFSET two_instruct
call WriteString
mov edx, OFFSET three_instruct
call WriteString
intro endp
; Get User's Input. Validate if Between Min and Max
input proc
; Prompt for user input
I1:
mov edx, OFFSET int_prompt
call WriteString
mov eax, 0
call ReadInt
call Crlf
; Check if less than MAX_VAL
cmp eax, MAX_VAL
JA I4
JMP I3
I3:
; Check if greater than MIN_VAL
cmp eax, MIN_VAL
JB I4
JMP I2
I4:
; EAX is incorrect
; Loop
mov edx, OFFSET bad_prompt
call WriteString
loop I1
; Good Input
; Set n_comps to eax
I2:
mov n_comps, eax
mov eax, 0
RET
input endp
; X is not divisible by 2 or 3, is prime
calculate proc
mov ecx, 400
mov x, 1
C1:
; Check if X is less than, or equal to, 3
cmp x, 3
JBE C2
C4:
; Check if X is divisible by 2
mov edx, 0
mov eax, x
mov ebx, 2
div ebx
cmp edx, 0
JE C3
; Check if X is divisible by 3
mov edx, 0
mov eax, x
mov ebx, 3
div ebx
cmp edx, 0
JNE C2
C3:
; Is composite, Print number
mov eax, x
cmp count, 10
JNE C5
call Crlf
mov count, 0
C5:
call WriteInt
call spacer_choice
mov edx, OFFSET spacer
call WriteString
add count, 1
C2:
; RET if X == N
mov eax, n_comps
cmp x, eax
JNE C6
RET
C6:
; Increment and LOOP
add x, 1
LOOP C1
calculate endp
; Define the spacer based on the places in x
spacer_choice proc
cmp x, 10
JB SC1
cmp x, 100
JB SC2
mov edx, OFFSET hundo_spacer
JMP SC3
SC1:
mov edx, OFFSET one_spacer
JMP SC3
SC2:
mov edx, OFFSET ten_spacer
JMP SC3
SC3:
mov spacer, OFFSET edx
RET
spacer_choice endp
; Say Goodbye
outro proc
mov edx, OFFSET farewell
call WriteString
mov edx, OFFSET username
call WriteString
call Crlf
outro endp
end main
I added the ASCII horizontal tab, 9, to the end of spacer, and that removed the need for the spacer_choice procedure.
Spacer now is declared as: spacer BYTE ",", 9, 0
Related
I'm trying to print an equilateral triangle made of * in NASM based off of user input that can be from numbers 01 to 99. So if the user inputs 99 the bottom row of the triangle will have 99 stars, then the row above that would have 97 stars, then above that row 95 stars, etc. but it is only making a rectangle with the same width and length. How can I change my code so that it will print an equilateral triangle and not a rectangle? Thanks for the help.
section .data
star: db '*', 1
starLen1: equ $-star
;endl
newLineMsg: db 0xA, 0xD
newLineLen: equ $-newLineMsg
section .bss
TriangleSize resb 1 ;Holds width of triangle
TriangleSize2 resb 1
spacebewteenvalues resb 1 ;take space bwteen values
loopcounter1 resb 2 ;hold count for first loop
loopcounter2 resb 2 ;hold count for 2nd loop
answer2 resb 2 ;hold first digital after times 10 for second input
answer3 resb 2 ;hold value after plus 2nd digit
section .text
global _start
_start:
mov eax,3
mov ebx,0
mov ecx,TriangleSize
mov edx,1
int 80h
mov eax,3
mov ebx,0
mov ecx,TriangleSize2
mov edx,1
int 80h
;sub ascii from each digit
sub [TriangleSize], byte '0'
sub [TriangleSize2], byte '0'
;multiply first digit by 10
mov al, [TriangleSize]
mov bl, 10
mul bl
;move into variable
mov [answer2], ax
;add 2nd digit
mov al, [answer2]
add al, [TriangleSize2]
;move both digit into variable
mov [answer3], al
;convert to decimal
add [answer3], byte '0'
;reset loop
mov [loopcounter1], byte '0'
mov [loopcounter2], byte '1'
;Start to cout *
jmp TriFunction1
;outputs first row
TriFunction1:
;move counter into reigster
mov al, [loopcounter1]
;compare row length then jump to next row
cmp al, [answer3]
je CoutNewline ;endl
;cout *
mov eax,4
mov ebx,1
mov ecx,star
mov edx,1
int 80h
;inc the loop counter
add [loopcounter1], byte 1
;jump back to beginning
jmp TriFunction1
;goes to next row
TriFunction2:
;move 2nd loop counter into register
mov al, [loopcounter2]
;compare
cmp al, [answer3]
je end ;when rectangle has finished drawing go back to main
add [loopcounter2], byte 1
;output the next row of *
jmp TriFunction1
;endl
CoutNewline:
;out \n
mov edx, newLineLen
mov ecx, newLineMsg
mov ebx, 1
mov eax, 4
int 0x80
;reset loop
mov [loopcounter1], word '0'
;check for next row
jmp TriFunction2
end:
mov eax,1 ; The system call for exit (sys_exit)
mov ebx,0 ; Exit with return code of 0 (no error)
int 80h;
;takes space between user input
takespacebetweennumbers:
mov eax,3
mov ebx,0
mov ecx,spacebewteenvalues
mov edx,1
int 80h
ret ;return back
Try to draw the expected output and then analyze how to achieve the result.
It's always better to divide a complex task into small steps.
I replaced the tail of your code from the line ;move both digit into variable:
;move both digit into variable
mov [answer3], al
; AL is now binary size of the triangle side (00..99). Examples:
; AL=07 Spaces Asterixes
; * 3 1
; *** 2 3
; ***** 1 5
;******* 0 7
; AL=08 Spaces Asterixes
; ** 3 2
; **** 2 4
; ****** 1 6
;******** 0 8
SECTION .data
Space DB ' '
Asterix DB '*'
NewLine DB 10
SECTION .bss
Spaces RESB 1
Asterixes RESB 1
Rows RESB 1
SECTION .text
; Calculate Spaces and Asterixes from triangle Size in AL.
CMP AL,1
JNA end
DEC AL
SHR AL,1 ; AL=(Size-1)/2, CF=1 if Size was even.
MOV [Spaces],AL
MOV AH,1
ADC AH,0 ; Start the 1st row with 1 or 2 asterixes.
MOV [Asterixes],AH
INC AL
MOV [Rows],AL
NextLine:
CALL PrintSpaces
CALL PrintAsterixes
CALL PrintNewLine
DEC BYTE [Spaces]
ADD BYTE [Asterixes],2
DEC BYTE [Rows]
JNZ NextLine
end:
mov eax,1 ; The system call for exit (sys_exit)
mov ebx,0 ; Exit with return code of 0 (no error)
int 80h;
PrintSpaces:
LEA ECX,[Space] ; Address of a character to print.
MOVZX EBP,BYTE [Spaces] ; How many times.
JMP Print
PrintAsterixes:
LEA ECX,[Asterix] ; Address of a character to print.
MOVZX EBP,BYTE [Asterixes] ; How many times.
JMP Print
PrintNewLine:
LEA ECX,[NewLine] ; Address of a character to print.
MOV EBP,1 ; How many times.
Print:
TEST EBP,EBP ; How many times to repeat the character.
JZ No
MOV EBX,1 ; Standard output handle.
MOV EDX,1 ; Print one character addressed by ECX.
NextChar:
MOV EAX,4 ; Invoke kernel function sys_write.
INT 80h
DEC EBP
JNZ NextChar ; Repeat EBP times.
No:RET
Modification which will draw a diamond shape instead of triangle:
; AL is now binary size of the diand width side (00..99). Examples:
; AL=07 Spaces Asterixes
; * 3 1
; *** 2 3
; ***** 1 5
;******* 0 7
; ***** 1 5
; *** 2 3
; * 3 1
; AL=08 Spaces Asterixes
; ** 3 2
; **** 2 4
; ****** 1 6
;******** 0 8
; ****** 1 6
; **** 2 4
; ** 3 2
SECTION .text
; Calculate Spaces and Asterixes from triangle Size in AL.
CMP AL,1
JNA end
DEC AL
SHR AL,1 ; AL=(Size-1)/2, CF=1 if Size was even.
MOV [Spaces],AL
MOV AH,1
ADC AH,0
MOV [Asterixes],AH
INC AL
MOV [Rows],AL
UpperLines: ; The upper half of the diamond.
CALL PrintSpaces
CALL PrintAsterixes
CALL PrintNewLine
DEC BYTE [Spaces]
ADD BYTE [Asterixes],2
DEC BYTE [Rows]
JNZ UpperLines
SUB BYTE [Asterixes],2 ; Rollback the middle line of the diamond.
INC BYTE [Spaces]
LowerLines: ; The lower half of the diamond.
SUB BYTE [Asterixes],2
INC BYTE [Spaces]
CALL PrintSpaces
CALL PrintAsterixes
CALL PrintNewLine
CMP BYTE [Asterixes],2
JNB LowerLines
end:
Task: output the number in hexadecimal form to the console. After that print some string (let it be "String after num").
The first part is successful, but the second is not.
The input number is stored in memory by the num label.
String is stored in memory by the line label.
String length - lines.
Code:
global _start
section .data
num db 01111110b
temp db 0
line db 10, "String after num", 10
lines equ $-line
section .text
_start:
call write_hex ; write num in hex format
mov eax, 4 ; write "Hello world!"
mov ebx, 1 ;
mov ecx, line ;
mov edx, lines ;
int 80H ;
mov eax, 1 ; exit
xor ebx, ebx
int 80H
write_hex:
mov eax, [num]
mov [temp], eax
shr byte [num], 4
call to_hex_digit
call write_digit
mov eax, [temp]
mov [num], eax
and byte [num], 1111b
call to_hex_digit
call write_digit
ret
to_hex_digit:
add [num], byte '0'
cmp [num], byte '9'
jle end
add [num], byte 7
end: ret
write_digit:
mov eax, 4
mov ebx, 1
mov ecx, num
mov edx, 1
int 80H
ret
Output:
Thanks for any help.
I used an invalid register to store a temporary value. I replaced the register which will work with the temp from eax to al. See Jester's answer.
I'm making new post about the same program - I'm sorry but I think that my question is much different than the previous one. My program gets 2 parameters at the start - number of repeats and a string. Number of repeats determines how many times should the last word from string be printed. For example:
./a.out 3 "ab cd"
shows in output
cdcdcd
I already made ( with Stack users help :-) ) a working program using call printf. It works for 0-9 number of repeats only but it's not as imporant as the main thing - my question is how to replace this "call printf" with sys_write calling.
I got information that I have to compile this using
-nostdlib
option but it doesn't matter if my code isn't correct. I tried my best and I also found some information about possible methods here but I can't make it work properly.
Printing new line works good but I have no idea how to deal with string from parameter #2 connected with sys_write. It would be great if someone more experienced find some time and point out what I need to change in the code. It took some time to get through the "call printf" version but then I was able to experiment and now I'm totally lost. Here it is:
.intel_syntax noprefix
.globl _start
.text
_start:
push ebp
mov ebp, esp
mov ecx, [ebp + 4] # arg1 int ECX
mov ebx, [ebp + 8] # arg2 string EBX
xor eax, eax
# ARG1 - FROM STRING TO INT
atoi:
movzx edx, byte ptr [ecx]
cmp edx, '0'
jb programend
sub edx, '0'
mov ecx, edx
## =========================== FUNCTION =========================== ##
# SEARCH FOR END OF STRING
findend:
mov dl, byte ptr [ebx + eax] # move through next letters
cmp dl, 0
jz findword
inc eax
jmp findend
# SEARCH FOR LAST SPACE
findword:
dec eax
mov dl, byte ptr [ebx + eax]
cmp dl, ' '
jz foundwordstart
jmp findword
# REMEMBER SPACE POSITION, CHECK COUNTER >0
foundwordstart:
push eax # remember space position
cmp ecx, 0 # check if counter > 0
jz theend
jmp foundword
# PRINT LAST WORD
foundword:
inc eax
mov dl, byte ptr [ebx + eax]
cmp dl, 0
jz checkcount
push ecx
push eax # save current position in word
push edx
push ebx
lea ecx, [ebx+eax] # char * to string
mov eax, 4 # sys_write
mov edx, 1; # how many chars will be printed
mov ebx, 1 # stdout
int 0x80
pop ebx
pop edx
pop eax
pop ecx
jmp foundword
# decrease counter and restore beginning of last word
checkcount:
dec ecx # count = count-1
pop eax # restore beginning of last word
jmp foundwordstart
theend:
pop eax # pop the space position from stack
jmp programend
# END OF PROGRAM
programend:
pop ebp
# new line
mov eax,4
mov ebx,1
mov ecx,offset msgn
mov edx,1
int 0x80
# return 0
mov eax, 1
mov ebx, 0
int 0x80
.data
msgn: .ascii "\n"
It's also really strange for me that I can run it with:
mov ecx, [ebp + 12]
mov ecx, [ecx + 8]
add ecx, eax # char * to string
mov eax, 4 # sys_write
mov edx, 1; # how many chars will be printed
mov ebx, 1 # stdout
int 0x80
and it works well - but only if I don't use -nostdlib (and of course I have to change _start to main)...
Hi every one I am trying to do a tower of Hanoi in assembly x86 but I am trying to use arrays. So this code gets a number from user as a parameter in Linux, then error checks a bunch of stuff. So now I just want to make the algorithm which use the three arrays i made (start, end, temp) and output them step by step. If someone can help it would be greatly appreciated. `
%include "asm_io.inc"
segment .data ; where all the predefined variables are stored
aofr: db "Argument out of Range", 0 ; define aofr as a String "Argument out of Range"
ia: db "Incorrect Argument", 0 ; define ia as a String "Incorrect Argument"
tma: db "Too many Arguments", 0 ; define tma as a String "Too many Arguments"
hantowNumber dd 0 ; define hantowNumber this is what the size of the tower will be stored in
start: dd 0,0,0,0,0,0,0,0,9 ; this array is where all the rings start at
end: dd 0,0,0,0,0,0,0,0,9 ; this array is where all the rings end up at
temp: dd 0,0,0,0,0,0,0,0,9 ; this array is used to help move the rings
test: dd 0,0,0,0,0,0,0,0,9
; The next couple lines define the strings to show the pegs and what they look like
towerName: db " Tower 1 Tower 2 Tower 3 ", 10, 0
lastLineRow: db "XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX ", 10, 0
buffer: db " ", 0
fmt:db "%d",10,0
segment .bss ; where all the input variables are stored
segment .text
global asm_main ; run the main function
extern printf
asm_main:
enter 0,0 ; setup routine
pusha
mov edx, dword 0 ; set edx to zero this is where the hantowNumber is saved for now
mov ecx, dword[ebp+8] ; ecx has how many arguments are given
mov eax, dword[ebp+12] ; save the first argument in eax
add eax, 4 ; move the pointer to the main argument
mov ebx, dword[eax] ; save the number into ebx
push ebx ; reserve ebx
push ecx ; reserve ecx
cmp ecx, dword 2 ; compare if there are more the one argument given
jg TmA ; if more then one argument is given then jump Too many Argument (TmA)
mov ecx, 0 ; ecx = 0
movzx eax, byte[ebx+ecx] ; eax is the first character number from the inputed number
sub eax, 48 ; subtract 48 to get the actual number/letter/symbol
cmp eax, 10 ; check if eax is less then 10
jg IA ; if eax is greater then 10 then it is a letter or symbol
string_To_int: ; change String to int procedure
add edx, eax ; put the number in edx
inc ecx ; increase counter (ecx)
movzx eax, byte[ebx+ecx] ; move the next number in eax
cmp eax, 0 ; if eax = 0 then there are no more numbers
mov [hantowNumber], edx ; change hantowNumber to what ever is in edx
je rangeCheck ; go to rangeCheck to check if between 2-8
sub eax, 48 ; subtract 48 to get the actual number/letter/symbol
cmp eax, 10 ; check if eax is less then 10
jg IA ; if eax is greater then 10 then it is a letter or symbol
imul edx, 10 ; multiply edx by 10 so the next number can be added to the end
jmp string_To_int ; jump back to string_To_int if not done
rangeCheck: ; check the range of the number
cmp edx, dword 2 ; compare edx with 2
jl AofR ; if hantowNumber (edx) < 2 then go to Argument out of Range (AofR)
cmp edx, dword 8 ; compare edx with 8
jg AofR ; if hantowNumber (edx) > 8 then go to Argument out of Range (AofR)
mov ecx, [hantowNumber] ; move the number enterd by user in ecx
mov esi, 28 ; esi == 28 for stack pointer counter
setStart: ; set the first array the starting peg
mov [start+esi], ecx ; put ecx into the array
sub esi, 4 ; take one away from stack pointer conter
dec ecx ; take one away from ecx so the next number can go in to the array
cmp ecx, 0 ; compare ecx with 0
jne setStart ; if ecx != 0 then go to setStart loop
; This is the section where the algoritham should go for tower of hanoi
mov ecx, [hantowNumber]
towerAlgorithm:
cmp ecx, 0
jg Exit ; jump to Exit at the end of the program
dec ecx
IA:
mov eax, ia ; put the string in eax
push eax ; reserve eax
call print_string ; output the string that is in eax
call print_nl ; print a new line after the output
pop eax ; put eax back to normal
add esp, 4 ; takes 4 from stack
jmp Exit ; jump to Exit at the end of the program
AofR:
mov eax, aofr ; put the string in eax
push eax ; reserve eax
call print_string ; output the string that is in eax
call print_nl ; print a new line after the output
pop eax ; put eax back to normal
add esp, 4 ; takes 4 from stack
jmp Exit ; jump to Exit at the end of the program
TmA:
mov eax, tma ; put the string in eax
push eax ; reserve eax
call print_string ; output the string that is in eax
call print_nl ; print a new line after the output
pop eax ; put eax back to normal
add esp, 4 ; takes 4 from stack
jmp Exit ; jump to Exit at the end of the program
Exit: ; ends the program when it jumps to here
add esp, 9 ; takes 8 from stack
popa
mov eax, 0 ; return back to C
leave
ret
haha I'm doing the exact same assignment and stuck on the algorithm however though when running your code it seems to identify "too many arguments" even though only one argument is provided, consider this algorithm when dealing with arguments(don't forget ./ is considered the "first argument" since it is the zeroth argument provided):
enter 0,0
pusha
; address of 1st argument is on stack at address ebp+12
; address of 2nd arg = address of 1st arg + 4
mov eax, dword [ebp+12] ;eax = address of 1st arg
add eax, 4 ;eax = address of 2nd arg
mov ebx, dword [eax] ;ebx = 2nd arg, it is pointer to string
mov eax, 0 ;clear the register
mov al, [ebx] ;it moves only 1 byte
sub eax, '0' ;now eax contains the numeric value of the firstcharacter of string
I have code here that reads in input to determine the dimensions of a matrix/2d array and then reads in numbers one by one. Then it is SUPPOSED to spit out the smallest number.
However my comparison operator doesn't seem to be working? I've tried putting both as registers, with different variables and so on but for some reason eax with whatever happened to be the first entry in the array is ALWAYS smaller than the next number, even if this is clearly not the case.
So it always skips reassignment.
Code: Just skip straight to cmp eax,[num]
My guess is something is causing num, perhaps how its declared? Is always 'larger' than eax, is there extra fluff I am not aware of?
segment .bss
num: resw 1 ;For storing a number, to be read of printed....
nod: resb 1 ;For storing the number of digits....
temp: resb 2
matrix1: resw 200
m: resw 1
n: resw 1
i: resw 1
j: resw 1
small: resb 4 ; temp variable
buff resb 4
segment .data
msg1: db "Enter the number of rows in the matrix : "
msg_size1: equ $-msg1
msg2: db "Enter the elements one by one(row by row) : "
msg_size2: equ $-msg2
msg3: db "Enter the number of columns in the matrix : "
msg_size3: equ $-msg3
msg4: db "The Smallest Number is... : "
msg_size4: equ $-msg4
tab: db 9 ;ASCII for vertical tab
new_line: db 10 ;ASCII for new line
segment .text
global _start
_start:
;; code for reading number of rows and columns, this works fine.
mov eax, 4
mov ebx, 1
mov ecx, msg1
mov edx, msg_size1
int 80h
;; read in rows
mov ecx, 0
call read_num
mov cx, word[num]
mov word[m], cx
mov eax, 4
mov ebx, 1
mov ecx, msg3
mov edx, msg_size3
int 80h
;; read in columns
mov ecx, 0
call read_num
mov cx, word[num]
mov word[n], cx
mov eax, 4
mov ebx, 1
mov ecx, msg2
mov edx, msg_size2
int 80h
;; Reading in each element and storing it into the array
mov esi, 0
mov ebx, matrix1
;; init loop
mov word[i], 0
mov word[j], 0
;; Outer loop
i_loop:
mov word[j], 0
;; Inner Loop
j_loop:
;; A function
call read_num
;; Result of that function is now stored int he matrix
mov dx , word[num]
mov word[ebx + 2 * esi], dx
inc esi ;Incrementing array index by one....
inc word[j]
mov cx, word[j]
cmp cx, word[n]
jb j_loop
;; End Inner Loop
inc word[i]
mov cx, word[i]
cmp cx, word[m]
jb i_loop
;; End Outer Loop
;; Now begins the code to find the smallest number
mov eax, [matrix1]
;; Moves first element of Matrix1 into eax
;;; saves eax into small
mov [small], eax
;Loop through the matrix, check each number if its smaller than the first number in the array. AT the end print said number.
;Reading each element of the matrix.(Storing the elements in row major order).......
mov esi, 0
mov edi, matrix1
;; Reinit loop cters
mov word[i], 0
mov word[j], 0
;; Loop
i_loop2:
mov word[j], 0
j_loop2:
;eax will contain the array index and each element is 2 bytes(1 word) long
mov dx, word[edi+2*esi] ;
mov word[num] , dx
cmp eax,[num] ; compares eax and ebx
jle skip ;if eax is SMALLER than ebx, we can safely skip reassignment
;as our current value is already smallest.
mov eax, [num] ; stores new smallest number if the new number was smaller.
mov [small], eax
;; reassignment code is always skipped.
skip:
inc esi
inc word[j]
mov cx, word[j]
cmp cx, word[n]
jb j_loop2
inc word[i]
mov cx, word[i]
cmp cx, word[m]
jb i_loop2
; code to output the smallest number
;; Some ui text.
mov eax, 4
mov ebx, 1
mov ecx, msg4
mov edx, msg_size4
int 80h
mov ecx, 0
;; Now the actual smallest number
mov eax, 4 ; system_write
mov ebx, 1 ; stdout
mov ecx, [small] ; move smallest element to accumulator
add ecx, 48 ; convert to ascii representation
mov [buff], ecx ; move to memory
mov ecx, buff
mov edx, 4 ; size, 4 bytes
int 80h
exit:
mov eax, 1
mov ebx, 0
int 80h
;Function to read a number from console and to store that in num
read_num:
pusha
mov word[num], 0
loop_read:
mov eax, 3
mov ebx, 0
mov ecx, temp
mov edx, 1
int 80h
cmp byte[temp], 10
je end_read
mov ax, word[num]
mov bx, 10
mul bx
mov bl, byte[temp]
sub bl, 30h
mov bh, 0
add ax, bx
mov word[num], ax
jmp loop_read
end_read:
popa
ret
Oh yes, several hours of fidgeting and seconds after this post I figured out exactly why. Turns out yes, the way I declared "num" yes indeed added in extra information. I changed it to resb 4 and it works.
Crabbaskets.