80836 Assembly ( 57 53 octets)
53 55 89 E5 8B 4D 0C 8B 55 10 B0 0A 30 DB 88 CF 00 C1 00 C2 49 4A 8A 01 8A 22 00 E0 00 D8 2C 30 30 DB 3C 39 7E 04 B3 01 2C 0A 88 01 88 22 38 CF 75 E2 5D 5B C3
Cela ajoute, chiffre par chiffre, de droite à gauche, sans convertir les chiffres ascii '0'-'9'
en nombres entiers 0-9
, et reporter si nécessaire. Le bytecode est le code d'une fonction, qui peut être appelée en C (voir ci-dessous).
Le bytecode ci-dessus a été écrit à la main, à partir de l'assemblage suivant (style NASM, commenté):
; save ebx, ebp
push ebx ; 53
push ebp ; 55
; copy esp
mov ebp, esp ; 8B EC
; load arguments
mov ecx, [ebp+0x0C] ; 8B 4D 0C
mov edx, [ebp+0x10] ; 8B 55 10
; initialize stuff
mov al, 10 ; B0 0A
xor bl, bl ; 30 DB
mov bh, cl ; 88 CF
; send edx, ecx to end of string
add cl, al ; 00 C1
add dl, al ; 00 C2
; decrement everything
dec ecx ; 49
dec edx ; 4A
; get rightmost unprocessed digit of each number
mov al, [ecx] ; 8A 01
mov ah, [edx] ; 8A 22
; add two ascii digits
add al, ah ; 00 E0
; add carry if needed
add al, bl ; 00 D8
; subtract 0x30 ('0') to get the resulting ascii digit
sub al, 0x30 ; 2C 30
; set bl to 0
xor bl, bl ; 30 DB
; if greater than '9': must carry over to next place
cmp al, 0x39 ; 3C 39
jle $+6 ; 7E 04
; set bl to 1 if carrying over
mov bl, 1 ; B3 01
; subtract 10 from ascii digit if carrying over
sub al, 0x0A ; 2C 0A
mov [ecx], al ; 88 01
mov [edx], ah ; 88 22
; check if loop has ended
cmp bh, cl ; 38 CF
jne $-28 ; 75 E2
; restore ebx, ebp
pop ebp ; 5D
pop ebx ; 5B
; return
ret ; C3
Pour essayer ceci en C (gcc, linux, processeur Intel):
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
int main(){
// bytecode from earlier
char code[] = {
0x53, 0x55, 0x8B, 0xEC, 0x8B, 0x4D, 0x0C, 0x8B,
0x55, 0x10, 0x31, 0xC0, 0xB0, 0x09, 0x30, 0xDB,
0x01, 0xC1, 0x01, 0xC2, 0x40, 0x50, 0x8A, 0x01,
0x8A, 0x22, 0x00, 0xE0, 0x00, 0xD8, 0x2C, 0x30,
0x30, 0xDB, 0x3C, 0x39, 0x7E, 0x04, 0xB3, 0x01,
0x2C, 0x0A, 0x88, 0x01, 0x88, 0x22, 0x58, 0x48,
0x49, 0x4A, 0x85, 0xC0, 0x75, 0xDF, 0x5D, 0x5B,
0xC3,
};
// allocate executable memory to a function pointer called 'add'
void __attribute__( (__cdecl__) ) (*add)(char*,char*) = mmap(0,sizeof code,PROT_WRITE|PROT_EXEC,MAP_ANON|MAP_PRIVATE,-1,0);
memcpy(add, code, sizeof code);
// test inputs
char number1[] = "0878295272", number2[] = "8184206821";
puts(number1);
puts(number2);
// call the bytecode as a c function
add(number1, number2);
// output is in the first argument
puts(number1);
// release allocated memory
munmap(add, sizeof code);
return 0;
}