Star InactiveStar InactiveStar InactiveStar InactiveStar Inactive
 
main.cpp
#include <stdio.h>

extern "C" int NumFibVals;
extern "C" int MemoryAddressing(int i, int* v1, int* v2, int* v3, int* v4);

int main(int argc, char* argv[])
{
    for (int i = -1; i < NumFibVals + 1; i++)
    {
        int v1 = -1, v2 = -1, v3 = -1, v4 = -1;
        int rc = MemoryAddressing(i, &v1, &v2, &v3, &v4);

        printf("i: %2d  rc: %2d - ", i, rc);
        printf("v1: %5d v2: %5d v3: %5d v4: %5d\n", v1, v2, v3, v4);
    }
    return 0;
}
memoryaddressing.asm
; Name:         memoryaddressing.asm
;
; Build:    g++ -m32 -c main.cpp -o main.o
;           nasm -f elf32 -o memoryaddressing.o memoryaddressing.asm
;           g++ -m32 -o memoryaddressing memoryaddressing.o main.o
;
; Source:       Modern x86 Assembly Language Programming p.42

global  MemoryAddressing
global  NumFibVals

section .data

; Simple lookup table

FibVals:    dd 0, 1, 1, 2, 3, 5, 8, 13
            dd 21, 34, 55, 89, 144, 233, 377, 610 

; extern "C" int NumFibVals;

NumFibVals: dd ($ - FibVals) / 4			; sizeof word = 4

section .text

; extern "C" int MemoryAddressing(int i, int* v1, int* v2, int* v3, int* v4);
;
;
; Description:  This function demonstrates various addressing modes
;               that can be used to access operands in memory.
;
; Returns:      0 = error (invalid table index)
;               1 = success

%define i   dword[ebp+8]
%define v1  dword[ebp+12]
%define v2  dword[ebp+16]
%define v3  dword[ebp+20]
%define v4  dword[ebp+24]
	
MemoryAddressing:	
    push    ebp
    mov     ebp,esp
    push    ebx
    push    edi
    push    esi
    ; Make sure 'i' is valid
    xor     eax,eax
    mov     edi, i
    cmp     edi, 0
    jl      .invalidIndex           ;jump if i < 0
    cmp     edi,[NumFibVals]
    jge     .invalidIndex           ;jump if i >= NumFibVals_
    ; Example #1 - base register
    mov     ebx, FibVals            ;rbx = FibVals
    shl     edi, 2                  ;rsi = i * 4
    add     ebx, edi                ;rbx = FibVals + i * 4
    mov     eax, [ebx]              ;Load table value
    mov     esi, v1
    mov     [esi], eax              ;Save to 'v1'
    ; Example #2 - base register + displacement
    ; esi is used as the base register
    mov     esi, i                  ;esi = i
    shl     esi, 2                  ;esi = i * 4
    mov     eax, [esi+FibVals]      ;Load table value
    mov     esi, v2
    mov     [esi],eax               ;Save to 'v2'
    ; Example #3 - base register + index register
    mov     ebx, FibVals            ;ebx = FibVals
    mov     esi, i                  ;esi = i
    shl     esi, 2                  ;esi = i * 4
    mov     eax, [ebx+esi]          ;Load table value
    mov     esi, v3
    mov     [esi],eax               ;Save to 'v3'
    ; Example #4 - base register + index register * scale factor
    mov     ebx, FibVals            ;ebx = FibVals
    mov     esi, i                  ;esi = i
    mov     eax, [ebx+esi*4]        ;Load table value
    mov     esi, v4
    mov     [esi], eax              ;Save to 'v4'
    mov     eax,1                   ;Set return code
.invalidIndex:
    pop     esi
    pop     edi
    pop     ebx
    pop     ebp
    ret
build
g++ -m32 -c main.cpp -o main.o
nasm -f elf32 -o memoryaddressing.o memoryaddressing.asm
g++ -m32 -o memoryaddressing memoryaddressing.o main.o