Hello,
this is the second example of the book "PC Assembly Language" by Paul A. Carter. It takes some time to study the theory (and will take some more time to understand it).
For using the code in Oxygen I tried to create a function and a sub. Using the function works quite nice.
;
; file: math1.o2bas
; This program demonstrates how the integer multiplication and division
; instructions work.
;
#include "$/inc/console.inc"
;segment .data
;
; Output strings
;
zstring
prompt = "Enter a number: ",
square_msg = "Square of input is ",
cube_msg = "Cube of input is ",
cube25_msg = "Cube of input times 25 is ",
quot_msg = "Quotient of cube/100 is ",
rem_msg = "Remainder of cube/100 is ",
neg_msg = "The negation of the remainder is "
;segment .bss
;entry resd 1
int entry
print prompt
entry = val (rtrim ltrim input())
function do_math(int num) as string
int square, cube, cube25, quot, rem_, neg_
pushad ' save registers
mov eax, num
imul eax ; edx:eax = eax * eax
mov square, eax
mov ebx, eax ; save answer in ebx
imul ebx, [num] ; ebx *= [num]
mov eax, ebx
mov cube, eax
imul ecx, ebx, 25 ; ecx = ebx*25
mov eax, ecx
mov cube25, eax
mov eax, ebx
cdq ; initialize edx by sign extension
mov ecx, 100 ; can't divide by immediate value
idiv ecx ; edx:eax / ecx
mov ecx, eax ; save quotient into ecx
mov eax, ecx
mov quot, eax
mov eax, edx
mov rem_, eax
neg edx ; negate the remainder
mov eax, edx
mov neg_, eax
popad ' restore registers
' Output
string s = square_msg + square + cr +
cube_msg + cube + cr +
cube25_msg + cube25 + cr +
quot_msg + quot + cr +
rem_msg + rem_ + cr +
neg_msg + neg_ + cr
return s
end function
print do_math(entry)
printl "Enter ..." : waitkey
For using the code in a sub I had to replace "ebx" with "esi". I assume the reason is because I used variables which are created outside the sub? I thought the use of pushad / popad would be sufficient but it seems I missed something else.
I wonder if there is a way to use "ebx" in the example which uses sub?
Roland
;
; file: math2.o2bas
; This program demonstrates how the integer multiplication and division
; instructions work.
;
#include "$/inc/console.inc"
;segment .data
;
; Output strings
;
zstring
prompt = "Enter a number: ",
square_msg = "Square of input is ",
cube_msg = "Cube of input is ",
cube25_msg = "Cube of input times 25 is ",
quot_msg = "Quotient of cube/100 is ",
rem_msg = "Remainder of cube/100 is ",
neg_msg = "The negation of the remainder is "
;segment .bss
int entry
int square, int cube, cube25, quot, rem_, neg_
print prompt
entry = val (rtrim ltrim input())
sub do_math(int num)
pushad ' save registers
mov eax, num
imul eax ; edx:eax = eax * eax
mov square, eax
mov esi, eax ; save answer in ebx
imul esi, [num] ; ebx *= [num]
mov eax, esi
mov cube, eax
imul ecx, esi, 25 ; ecx = ebx*25
mov eax, ecx
mov cube25, eax
mov eax, esi
cdq ; initialize edx by sign extension
mov ecx, 100 ; can't divide by immediate value
idiv ecx ; edx:eax / ecx
mov ecx, eax ; save quotient into ecx
mov eax, ecx
mov quot, eax
mov eax, edx
mov rem_, eax
neg edx ; negate the remainder
mov eax, edx
mov neg_, eax
popad ' restore registers
end sub
do_math(entry)
' Output
string s = square_msg & square & cr &
cube_msg & cube & cr &
cube25_msg & cube25 & cr &
quot_msg & quot & cr &
rem_msg & rem_ & cr &
neg_msg & neg_ & cr
print s
printl "Enter ..." : waitkey
.