Download Lab_6_Slides

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
AGENDA
Runtime stack.
 Procedures




Procedures Definition
Procedures Call
Sum Integer Array Example
CALL and RET Instructions
 Passing Parameters to Procedures


Using Registers



Sum Integer Array Example (Using Registers)
Using Stack (Manually)
Using Stack and Invoke Directive
Defining Procedures Declaration, Definition, and Call
 Sum Integer Array Example (Using Stack)
 Hands On

2
RUNTIME STACK
WHAT IS RUNTIME STACK?
Same as stack :

FILO (First In Last Out) / LIFO
 Temporary
array (segment) in the
memory managed by the CPU.
 It’s
managed using SS & ESP registers
4
EXAMPLE
Stack
 Push
x
 Push y
 Pop
 Push z
ESP
X
1000
Y
Z
FFC
FF8
5
WHY USE STACK?




Saving register values temporarily
Saving the return address of the called
procedures
Passing parameters to procedures
Local variables defined in a procedure are
created in its beginning and destroyed in its end.
6
STACK INSTRUCTIONS
PUSH r/m16 | r/m32 | imm32
POP r/m16 | r/m32
PUSHAD
in the following order :
EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI
POPAD
EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX)
7
PUSHFD/POPFD
Procedures
• As we know, we should not write the whole
program in a single chunk.
• Program code should be divided into pieces, each
piece performs specific function, takes specific
input, and produces specific output.
• We often called these pieces as functions or
procedures, but it still has the same meaning.
9
Procedures Definition
• To define a procedure, use PROC and ENDP
directives to encapsulate procedure code.
• For example, the following is the definition of a
function called Sample1:
Sample1 PROC
…
RET
Sample1 ENDP
10
Procedures Call
• To call a procedure, use CALL instruction, as follows:
CALL Sample1
11
Sum Integer Array Example
INCLUDE Irvine32.inc
.data
Arr1 DWORD 10,20,30,40,50
.code
main PROC
; main procedure begin
call SumArr
; call SumArr procedure
call writeint
; output the sum (which already
stored in EAX)
call CrLf
exit
main ENDP
;main procedure end
SumArr PROC
; SumArr procedure begins
mov esi, offset Arr1
;put array address in esi
mov eax, 0
;initialize eax by zero for sum
mov ecx, LENGTHOF Arr1
;initialize ecx by array size
sum_loop:
add eax, DWORD PTR [esi]
add esi, 4
; increment esi pointer by the size of
the array element
loop sum_loop
RET ;Return to the main procedure12
SumArr ENDP ; end of procedure
END main
Sum Integer Array Example
• As we write procedural code, we make the main
program code itself in a procedure called main
(however, it can take any other name).
13
Sum Integer Array Example
• The main procedure does not require a RET instruction
at its end, as it is ended by exit which terminates the
whole program and returns to Windows OS. (exit is an
alias for ExitProcess Windows API function).
• In contrast, the SumArr must ended by RET instruction to
allow return to the main program.
• If it is missed, the program continues execution to next
machine code which it does not correspond to a valid
machine instruction and causing a program crash.
14
Sum Integer Array Example
• The SumArr procedure calculates the summation in
EAX register and implicitly returns this value to the
main program in EAX itself.
• Returning values in registers is possible as the
registers values do not change when returning from a
procedure.
15
CALL and RET Instructions
• CPU knows the next instruction by storing its address
in EIP (Instruction Pointer) register.
• So, at any time during the program run, EIP contains
the address of next instruction to be executed.
• Therefore, to change the program flow by a jump or
CALL instructions, CPU updates the EIP value to
be the address of the jumped instruction or the
address of the called procedure.
17
CALL and RET Instructions
• A trivial question popped in mind, how RET instruction
knows the correct address to return to after a procedure
end?
• This can be accomplished by saving the return
address which is the address of the next instruction
after CALL instruction.
• Well, good answer, but where to save it?
• The most suitable place to save the return address is
the stack. Therefore, return address is pushed by
CALL instruction and popped by RET instruction. 18
CALL and RET Instructions
Address
00000020
00000025
00000040
Code
main PROC
call MySub
mov eax, ebx
…
main ENDP
MySub PROC
mov eax, edx
…
RET
MySub ENDP
19
Passing Parameters to Procedures
• Using Registers.
• Using Stack (Manually).
• Using Stack and Invoke Directive.
21
Sum Integer Array Example
INCLUDE Irvine32.inc
.data
Arr1 DWORD 10,20,30,40,50
.code
main PROC
; main procedure begin
call SumArr
; call SumArr procedure
call writeint
; output the sum (which already
stored in EAX)
call CrLf
exit
main ENDP
;main procedure end
SumArr PROC
; SumArr procedure begins
mov esi, offset Arr1
;put array address in esi
mov eax, 0
;initialize eax by zero for sum
mov ecx, LENGTHOF Arr1
;initialize ecx by array size
sum_loop:
add eax, DWORD PTR [esi]
add esi, 4
; increment esi pointer by the size of
the array element
loop sum_loop
RET ;Return to the main procedure22
SumArr ENDP ; end of procedure
END main
Passing Parameters to Procedures
Using Registers
• In the example of summing the integer array
elements, we saw how to sum integer arrays by a
separate procedure from the main program.
• But it has a problem, it runs only on fixed array (i.e.
Arr1) with fixed length, and so this procedure
cannot be reused with any other array.
• So, we need to pass the array address and its length
to the procedure to be able to run on different
23
arrays with different lengths.
Passing Parameters to Procedures
Using Registers
• We can use general‐purpose registers to pass
parameters to procedures.
• As performed when calling WriteInt, or WriteString
procedures that are defined in Irvine library.
• They receive parameters in EAX and EDX registers
respectively.
24
Passing Parameters to Procedures
Using Registers
• The following example calculates the sum of an
integer array using a procedure which takes the
address of the array in ESI register and its length in
ECX register.
25
Sum Integer Array Example (Using
Registers)
INCLUDE Irvine32.inc
.data
arr1 DWORD 10,20,30,40,50
.code
main PROC ;main procedure
begin
mov esi, offset arr1 ;pass array
address in esi as a parameter
mov ecx, LENGTHOF arr1 ;pass
array length in ecx as a
parameter
call SumArr ;call SumArr
procedure to sum array
call writeint ;output the
summation
exit
main ENDP ;main procedure end
SumArr PROC procedure begins
;save the esi and ecx values from
changes happened inside this procedure
push esi
push ecx
mov eax, 0
sum_loop:
add eax, DWORD PTR [esi]
add esi, 4 ;increment esi pointer by 4
loop sum_loop
pop ecx ;restore ecx value from stack
pop esi ;restore esi value from stack
Ret ;Return execution to the main
procedure
26
SumArr ENDP ;SumArr procedure end
END main
Sum Integer Array Example (Using
Registers)
• SumArr procedure now uses ESI and ECX registers
as the array address and the array length
respectively, so it can be used with any integer array
of any length.
• As SumArr modifies the ESI and ECX registers:
• First, it pushes them in the stack to temporarily
save them.
• At the end, it pops the stack to restore their
values.
27
Passing Parameters to Procedures
Using Stack (Manually)
• Passing parameters using registers is limited
according to the limited number of registers.
• Therefore, there is a more efficient way to pass
parameters to procedures which pushes parameters
into runtime stack while the called procedure pops
them to work on.
28
Passing Parameters to Procedures
Using Stack and INVOKE Directive
• MASM provides an easy way to pass parameters in the
stack, by allowing PROC directive to accept a list of
parameters.
• In addition, INVOKE directive can be used to call
procedures with a list of arguments instead of CALL
instruction.
• You can do the job of passing parameters in the stack
manually without using INVOKE directive, but using
the INVOKE directive will simplify the operation
because it is much like calling functions in high‐level
29
languages.
Defining Procedures with Parameters
<Label>
…
…
RET
<Label>
PROC
paramName: type, ..., paramName: type
• paramName is an arbitrary name you assign to the parameter.
• type is the type of the parameter. It can be one of the
following:
• One of the known types (BYTE, WORD, DWORD, …).
• Pointer to one of the above types, to handle calling by
reference.
• To specify a pointer, use PTR specifier before the type
30
as follows, PTR BYTE, PTR WORD, etc.
Calling Procedures with Stack
Parameters
INVOKE procedureName [, argumentList]
• argumentList is a comma‐separated list of arguments
to be passed to the procedure named procedureName.
• INVOKE directive allows calling procedures
defined with stack parameters while CALL
instruction doesn’t.
31
Declaring Procedures
• A procedure must be defined before calling it by
INVOKE directive.
• Otherwise, assembler gives undefined symbol error.
• Therefore, we use PROTO directive to declare this
procedure, and put the definition anywhere in the
code.
32
Declaring Procedures
<Label>
PROTO
paramName: type, ..., paramName: type
• PROTO directive allows declaring the prototype of a
specific procedure.
• Procedure prototype can be placed in any location
before invoke statement, even inside main procedure.
• Note that the label declared in PROTO must match the
33
label specified in PROC directive.
Procedures Declaration, Calling, and
Definition
<Label> PROTO
paramName: type, ..., paramName: type
INVOKE procedureName , argument1, argument2, ..
<Label>
<Label>
PROC
…
…
RET
paramName: type, ..., paramName: type
34
Sum Integer Array Example (Using
Stack)
INCLUDE Irvine32.inc
.data
arr1 DWORD 10, 20, 30, 40, 50
.code
; Specify SumArr procedure
prototype
SumArr PROTO x:PTR DWORD,
sz: DWORD
main PROC
;use invoke directive to call
SumArr procedure and to specify
arguments
INVOKE SumArr, offset arr1,
lengthof arr1
call writeint
exit
main ENDP
;Specify SumArr procedure definition
SumArr PROC Addrs: PTR
DWORD, sze: DWORD
push esi
push ecx
mov eax, 0
mov esi, Addrs
mov ecx, sze
sum_loop:
add eax, DWORD PTR [esi]
add esi, 4
loop sum_loop
pop ecx
pop esi
35
Ret
SumArr ENDP
End main
1- String Reverse
• Write the code of a procedure that reverses an entered
string.
37
String Reverse
• ReverseString procedure takes two pointers: one to
the input string, while the other to the reversed
string. It also takes the size of the string.
• The pointer is defined by PTR operator followed
by the size that the pointer points to such as PTR
BYTE and PTR DWORD, etc.
38
String Reverse
• Readstring is an Irvine function that reads a string
from a user.
• It takes the address of the input buffer in EDX
and the maximum number of characters to read
in ECX.
• It fills the buffer by the input string and set EAX
by the size of the input string.
39
String Reverse
INCLUDE Irvine32.inc
.data
MAX_LEN EQU 80
prompt1 byte "Enter a string: ", 0
prompt2 byte "The reversed string: ", 0
strInp byte MAX_LEN + 1 Dup (?)
strOut byte MAX_LEN + 1 Dup (?)
.code
;the prototype of the ReverseString
procedure
ReverseString PROTO Src: PTR BYTE,
Dest: PTR BYTE, sze:DWORD
main PROC
mov edx, offset prompt1
call writestring
;to input a string from user, use ReadString
;[IN] EDX: address of the input buffer
mov edx, offset strInp
;[IN] ECX: Maximum number of
characters to read
mov ecx, MAX_LEN
call readstring
;[OUT] EAX: size of the input string
;Call ReverseString procedure and
pass its parameters
INVOKE ReverseString, offset
strInp, offset strOut, eax
mov edx, offset prompt2
call writestring
mov edx, offset strOut
call writestring
call crlf
exit
40
main ENDP
String Reverse
ReverseString PROC Src:PTR BYTE,
Dest:PTR BYTE, sze:DWORD
;save register values in stack
push ecx
push edi
push eax
mov ecx, sze
mov edi, Src
L1:
movzx eax, BYTE PTR [edi]
;push the source string in stack
push eax
inc edi
loop L1
mov ecx, sze
mov edi, Dest
L2:
pop eax
;pop the string from stack to the dest
string
mov [edi], al ;it is reversed
inc edi
loop L2
mov BYTE PTR [edi], 0
;terminate the reversed string by a null
char
pop eax
pop edi
pop ecx
Ret
41
ReverseString ENDP
END main
2- Palindrome
A palindrome is a string that reads the same
backwards as forwards. For example,
abcba, 1221, 55555 …etc.
Write an assembly program that reads a
string and its size and check if it is
palindrome or not.
42
Palindrome
MaxLength EQU 100
.data
strIn BYTE MaxLength+1 Dup (0)
; when Dup 0 no need to inset a null
terminating Char
strPrompet BYTE "Please enter
your string : ",0
strPal BYTE "Your string is
palindrome.",0
strNotPal BYTE "Your string is
not palindrome.",0
43
.code
; Proc prototype
CheckStringIsPalindrome PROTO strPtr
: PTR BYTE, strSize : DWORD
main PROC
MOV EDX, OFFSET strPrompet
;Write the prompet
CALL WriteString
MOV EDX, OFFSET strIn
MOV ECX, MaxLength
CALL ReadString
; Proc Call
INVOKE
CheckStringIsPalindrome
,OFFSET strIn, EAX
exit
main ENDP
Palindrome
CheckStringIsPalindrome PROC strPtr :
PTR BYTE, strSize : DWORD
PUSHAD
MOV ESI, strPtr
; points to the start of the string.
MOV EDI, strPtr
ADD EDI, strSize
DEC EDI ; points to the end of the string.
.WHILE ESI < EDI
44
MOV AL, BYTE PTR [ESI]
.IF AL != BYTE PTR [EDI]
MOV EDX, OFFSET strNotPal
JMP BreakLoop
.ENDIF
INC ESI
DEC EDI
.ENDW
MOV EDX, OFFSET strPal
BreakLoop:
CALL WriteString
CALL CRLF
POPAD
RET
CheckStringIsPalindrome ENDP
1- Write an assembly program that calculates the Fibonacci value
of the input index from user. Write the Fibonacci procedure
twice, once repetitive and another recursive. (The Fibonacci
series is 0, 1, 1, 2, 3, 5, 8, 13…).
2- Write an assembly program that computes the characters
frequencies of a given string. For example if a string given
‘adbdbbbaadd’, it should print:
a=3
b=4
d=4
3- Write an assembly program that validates the number and order
of parentheses in a mathematical expression input from user. It
should check that the number of right parentheses and left
parentheses are equal. Also, it checks every right (closing)
parenthesis is preceded by a matching left (opening)
46
parenthesis.