main.cpp
#include <stdio.h>
extern "C" int NumFibVals, FibValsSum;
extern "C" int MemoryAddressing(int i, int* v1, int* v2, int* v3, int* v4);
int main(int argc, char* argv[])
{
FibValsSum = 0;
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);
}
printf("FibValsSum: %d\n", FibValsSum);
return 0;
}
memoryaddressing.asm
; Name: memoryaddressing.asm
;
; Build: g++ -c main.cpp -o main.o
; nasm -f elf64 -o memoryaddressing.o memoryaddressing.asm
; g++ -o memoryaddressing memoryaddressing.o main.o
;
; Source: Modern x86 Assembly Language Programming p.512
bits 64
global MemoryAddressing
global FibVals
global NumFibVals
section .bss
;value to demo RIP-relative addressing
common FibValsSum 4 ;one dword to store result
;memory is global and shared amongst other modules
section .data
; Simple lookup table
FibVals: dd 0, 1, 1, 2, 3, 5, 8, 13, 21
dd 34, 55, 89, 144, 233, 377, 610, 987, 1597
NumFibVals: dd ($ - FibVals) / 4 ; sizeof dword = 4 bytes
section .code
; 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
MemoryAddressing:
; Make sure 'i' is valid
cmp edi,0
jl .invalidIndex ;jump if i < 0
cmp edi,[NumFibVals]
jge .invalidIndex ;jump if i >= NumFibVals_
; Sign extend i for use in address calculations
movsxd rdi,edi ;sign extend i
mov r9,rdi ;save copy of i
; Example #1 - base register
mov r11,FibVals ;r11 = FibVals
shl rdi,2 ;rdi = i * 4
add r11,rdi ;r11 = FibVals + i * 4
mov eax,[r11] ;eax = FibVals[i]
mov [rsi],eax ;Save to v1
; Example #2 - base register + index register
mov r11,FibVals ;r11 = FibVals
mov rdi,r9 ;rdi = i
shl rdi,2 ;rdi = i * 4
mov eax,[r11+rdi] ;eax = FibVals[i]
mov [rdx],eax ;Save to v2
; Example #3 - base register + index register * scale factor
mov r11,FibVals ;r11 = FibVals
mov rdi,r9 ;rdi = i
mov eax,[r11+rdi*4] ;eax = FibVals[i]
mov [rcx],eax ;Save to v3
; Example #4 - base register + index register * scale factor + disp
mov r11,FibVals-42 ;r11 = FibVals - 42
mov rdi,r9 ;rdi = i
mov eax,[r11+rdi*4+42] ;eax = FibVals[i]
mov [r8],eax ;Save to v4
; Example #5 - RIP relative
add [FibValsSum],eax ;Update sum
mov eax,1 ;set success return code
ret
.invalidIndex:
xor eax,eax ;set error return code
ret
build
g++ -c main.cpp -o main.o
nasm -f elf64 -o memoryaddressing.o memoryaddressing.asm
g++ -o memoryaddressing memoryaddressing.o main.o