Zweite korrigierte und erweiterte Antwort:
So, ich hab den Code jetzt mal getestet, und in meiner vorherigen Antwort waren natürlich ein paar Fehler drin. (Ist schon spät!) :)
Speichere folgenden Quelltext in "asmfunc.asm":
global xor_mem
section .text
xor_mem:
mov ecx, [esp + 8]
mov eax, [esp + 4]
mov edx, eax
add edx, ecx
.loop:
cmp eax, edx
je .done
xor [eax], byte 0xFE
inc eax
jmp .loop
.done:
ret
Das hier speicherst du in "asmfunc.h":
#pragma once
#ifndef GUARD_ASMFUNC_H
#define GUARD_ASMFUNC_H
#include <stdlib.h> /* size_t */
#ifdef __cplusplus
extern "C" {
#endif
void xor_mem(
void * const buf,
const size_t len
);
#ifdef __cplusplus
}
#endif
#endif
Das hier ist das Testprogramm "main.c":
#include <stdio.h> /* printf, puts */
#include <stdlib.h> /* EXIT_SUCCESS, size_t */
#include <string.h> /* strlen */
#include "asmfunc.h"
void dump(
const char * const msg,
const char * const buf,
const size_t len
) {
size_t c = '\0';
size_t i = 0;
size_t j = 0;
printf("%s: '%s'", msg, buf);
for (i = 0; i < len; ++i) {
printf("%s", i ? ", " : " => ");
c = ((size_t)buf[i]) & 0xFF;
j = 8;
while (j) {
printf("%c", !!(c & (1 << --j)) + '0');
}
}
puts("");
}
int main(void) {
char cstr[] = "foobar";
const size_t len = strlen(cstr);
dump("A", cstr, len);
xor_mem(cstr + 2, 3);
dump("B", cstr, len);
xor_mem(cstr + 2, 3);
dump("C", cstr, len);
return EXIT_SUCCESS;
}
Und zum bauen speicherst du eine "makefile":
prog != basename `pwd`
prog := $(prog).elf
srcs != find . -type f -name '*.c'
hdrs != find . -type f -name '*.h'
asms != find . -type f -name '*.asm'
cos := $(srcs:%.c=%.c.o)
aos := $(asms:%.asm=%.asm.o)
cc := gcc
cc_flags := \
-std=c89 -O0 -g -m32 \
-pedantic -Wall -Wextra -Wpedantic \
-Werror
.PHONY : all clean
all : clean $(prog)
time -p ./$(prog)
clean :
rm -vf *~ $(prog) *.o
$(prog) : $(cos) $(aos)
$(cc) $(cc_flags) -o $@ $^
%.c.o : %.c $(hdrs) makefile
$(cc) $(cc_flags) -o $@ -c $<
%.asm.o : %.asm makefile
nasm -f elf -o $@ $<
Wenn du diese 4 Dateien in einem leeren Verzeichnis gespeichert hast, tippst du einfach ...
make
... ein, und solltest - wenn alles glatt geht - neben vielen Ausgaben von make selbst, am Ende diese Ausgabe erhalten:
A: 'foobar' => 01100110, 01101111, 01101111, 01100010, 01100001, 01110010
B: 'fo???r' => 01100110, 01101111, 10010001, 10011100, 10011111, 01110010
C: 'foobar' => 01100110, 01101111, 01101111, 01100010, 01100001, 01110010
(Die Nicht-ASCII-Zeichen aus Zeile B habe ich mal durch Fragezeichen ersetzt, weil GF sonst meckert!)
Also wie du siehst, funktioniert die xor_mem() Funktion in Assembler einwandfrei, nachdem ich ein paar Schönheitsfehler korrigiert habe.
In dem Verzeichnis sollten jetzt zwei Objektdateien (mit Endung *.o) und eine ausführbare ELF-Datei (mit Endung *.elf) liegen.
Ich hab das mit gmake, gcc, yasm und nasm ausprobiert, und scheint alles zu funktionieren. Kannst ja mal selber mit rumspielen. :)