I am currently getting an "exception thrown" error on the line
mov [ebx], eax
I can't find a solution because all of them use this exact same code and it works for them.
This is an exact copy from my lecture notes and it seems to work for other people except for me.
TITLE Program Template (template.asm)
; Author:
; Last Modified:
; OSU email address:
; Course number/section:
; Project Number: Due Date:
; Description:
INCLUDE Irvine32.inc
.data
intro BYTE "Fun with Arrays! by ", 0
instruction BYTE "This program generates random numbers in the range [100 .. 999], displays the original list, sorts the list, and calculates the median value. Finally, it displays the list sorted in descending order.", 0
request DWORD ?
ask_user BYTE "How many numbers should be generated? [10 ... 200]: ", 0
.code
main PROC
;call randomize
call introduction
push OFFSET request
call getData
exit ; exit to operating system
main ENDP
introduction PROC
mov edx, OFFSET intro
call WriteString
call CrLf
mov edx, OFFSET instruction
call WriteString
call CrLf
introduction ENDP
getData PROC
push ebp
mov ebp, esp
mov edx, OFFSET ask_user
call WriteString
call ReadInt
mov ebx, [ebp+8]
mov [ebx], eax
pop ebp
ret 4
getData ENDP
END main
introduction
is missing a ret
Execution falls through from the last instruction of introduction
to the first instruction of getData
. Execution of machine-code always continues to the next address in memory after the current instruction (unless you use a call/ret/branch); labels and proc
declarations are just markers. (Why is no value returned if a function does not explicity use 'ret')
This happens without a valid pointer on the stack. (Because main
calls introduction
first, without first pushing an address.)
You can look for bugs like this in a debugger by single-stepping your code; the fall-through instead of return to main should catch your attention!
Or use your debugger's backtrace function to see where the call came from: you'll see you reached this line in getData
from call introduction
, not from call getData
.
I'd recommend using a call-clobbered (aka volatile) register for the temporary inside getData
. (EAX, ECX, or EDX). ebx
is normally call-preserved, so main
, and main's caller, expects their EBX value to still be there when the functions return. (But your main
doesn't return or use EBX, so there's no actual bug, just a custom calling convention.)