main.cpp
#include <stdio.h>
#include <inttypes.h>
#include "../../commonfiles/miscdefs.h"
// The following structure must match the structure that's
// declared in IntegerOperands.asm.
typedef struct
{
Uint8 a8;
Uint16 a16;
Uint32 a32;
Uint64 a64;
Uint8 b8;
Uint16 b16;
Uint32 b32;
Uint64 b64;
} ClVal;
extern "C" void CalcLogical(ClVal* cl_val, Uint8 c8[3], Uint16 c16[3], Uint32 c32[3], Uint64 c64[3]);
int main(int argc, char* argv[])
{
ClVal x;
Uint8 c8[3];
Uint16 c16[3];
Uint32 c32[3];
Uint64 c64[3];
x.a8 = 0x81; x.b8 = 0x88;
x.a16 = 0xF0F0; x.b16 = 0x0FF0;
x.a32 = 0x87654321; x.b32 = 0xF000F000;
x.a64 = 0x0000FFFF00000000; x.b64 = 0x0000FFFF00008888;
CalcLogical(&x, c8, c16, c32, c64);
printf("\nResults for CalcLogical()\n");
printf("\n8-bit operations\n");
printf("0x%02" PRIx8 " & 0x%02" PRIx8 " = 0x%02" PRIx8 "\n", x.a8, x.b8, c8[0]);
printf("0x%02" PRIx8 " | 0x%02" PRIx8 " = 0x%02" PRIx8 "\n", x.a8, x.b8, c8[1]);
printf("0x%02" PRIx8 " ^ 0x%02" PRIx8 " = 0x%02" PRIx8 "\n", x.a8, x.b8, c8[2]);
printf("\n16-bit operations\n");
printf("0x%04" PRIx16 " & 0x%04" PRIx16 " = 0x%04" PRIx16 "\n", x.a16, x.b16, c16[0]);
printf("0x%04" PRIx16 " | 0x%04" PRIx16 " = 0x%04" PRIx16 "\n", x.a16, x.b16, c16[1]);
printf("0x%04" PRIx16 " ^ 0x%04" PRIx16 " = 0x%04" PRIx16 "\n", x.a16, x.b16, c16[2]);
printf("\n32-bit operations\n");
printf("0x%08" PRIx32 " & 0x%08" PRIx32 " = 0x%08" PRIx32 "\n", x.a32, x.b32, c32[0]);
printf("0x%08" PRIx32 " | 0x%08" PRIx32 " = 0x%08" PRIx32 "\n", x.a32, x.b32, c32[1]);
printf("0x%08" PRIx32 " ^ 0x%08" PRIx32 " = 0x%08" PRIx32 "\n", x.a32, x.b32, c32[2]);
printf("\n64-bit operations\n");
printf("0x%020" PRIx64 " & 0x%020" PRIx64 " = 0x%020" PRIx64 "\n", x.a64, x.b64, c64[0]);
printf("0x%020" PRIx64 " | 0x%020" PRIx64 " = 0x%020" PRIx64 "\n", x.a64, x.b64, c64[1]);
printf("0x%020" PRIx64 " ^ 0x%020" PRIx64 " = 0x%020" PRIx64 "\n", x.a64, x.b64, c64[2]);
return 0;
}
integeroperands.asm
; Name: integeroperands.asm
;
; Build: g++ -c main.cpp -o main.o
; nasm -f elf64 -o integeroperands.o integeroperands.asm
; g++ -o integeroperands integeroperands.o main.o
;
; Source: Modern x86 Assembly Language Programming p.514
global CalcLogical
; The following structure must match the structure that's
; declared in IntegerOperands.cpp. Note the version below
; includes "pad" bytes, which are needed to account for the
; member alignments performed by the C++ compiler.
struc ClVal
.a8: resb 1
.pad1: resb 1
.a16: resw 1
.a32: resd 1
.a64: resq 1
.b8: resb 1
.pad2: resb 1
.b16: resw 1
.b32: resd 1
.b64: resq 1
endstruc
section .text
; extern "C" void CalcLogical(ClVal* cl_val, Uint8 c8[3], Uint16 c16[3], Uint32 c32[3], Uint64 c64[3]);
;
; Description: The following function demonstrates logical operations
; using different sizes of integers.
CalcLogical:
; 8-bit logical operations
mov r10b,[rdi+ClVal.a8] ;r10b = a8
mov r11b,[rdi+ClVal.b8] ;r11b = b8
mov al,r10b
and al,r11b ;calc a8 & b8
mov [rsi],al
mov al,r10b
or al,r11b ;calc a8 | b8
mov [rsi+1],al
mov al,r10b
xor al,r11b ;calc a8 ^ b8
mov [rsi+2],al
; 16-bit logical operations
mov r10w,[rdi+ClVal.a16] ;r10w = a16
mov r11w,[rdi+ClVal.b16] ;r11w = b16
mov ax,r10w
and ax,r11w ;calc a16 & b16
mov [rdx],ax
mov ax,r10w
or ax,r11w ;calc a16 | b16
mov [rdx+2],ax
mov ax,r10w
xor ax,r11w ;calc a16 ^ b16
mov [rdx+4],ax
; 32-bit logical operations
mov r10d,[rdi+ClVal.a32] ;r10d = a32
mov r11d,[rdi+ClVal.b32] ;r11d = b32
mov eax,r10d
and eax,r11d ;calc a32 & b32
mov [rcx],eax
mov eax,r10d
or eax,r11d ;calc a32 | b32
mov [rcx+4],eax
mov eax,r10d
xor eax,r11d ;calc a32 ^ b32
mov [rcx+8],eax
; 64-bit logical operations
mov r10,[rdi+ClVal.a64] ;r10 = a64
mov r11,[rdi+ClVal.b64] ;r11 = b64
mov rax,r10
and rax,r11 ;calc a64 & b64
mov [r8],rax
mov rax,r10
or rax,r11 ;calc a64 | b64
mov [r8+8],rax
mov rax,r10
xor rax,r11 ;calc a64 ^ b64
mov [r8+16],rax
ret
build
g++ -c main.cpp -o main.o
nasm -f elf64 -o integeroperands.o integeroperands.asm
g++ -o integeroperands integeroperands.o main.o