Author: Dann Corbit
Date: 07:42:56 07/05/02
Go up one level in this thread
On July 05, 2002 at 05:35:49, Uri Blass wrote:
>On July 05, 2002 at 04:33:40, Russell Reagan wrote:
>
>>On July 05, 2002 at 03:35:01, Uri Blass wrote:
>>
>>>The advise that Amir Ban gave me few years ago about chess programming is not to
>>>try to lean assembler.
>>>He suggested that I should learn C if I am serious about chess programming.
>>
>>That's odd. I thought he uses C++ :)
>
>Yes
>I know that he is using C++ but I learned only C and not C++.
>
>The point was comparing C with assembler and not comparing C with C++
Assembly language is definitely the easiest computer language to learn.
However, it takes a giant pile of instructions to accomplish anything.
Also, it is hard to maintain and when the chip upgrades happen, you are in for a
big mess.
For instance, here is a simple C program to calculate the towers of Hanoi:
#include <stdio.h>
void saigon(int *p, int n, int s, int t)
{
int a;
if (n == 1) {
s[p]--;
t[p]++;
printf("a:%d,%d,%d\n", 0[p], 1[p], 2[p]);
} else {
a = (t && s) ? 0 :
(t != 1 && s != 1) ? 1 : 2;
saigon(p, n - 1, s, a);
{
s[p]--;
t[p]++;
printf("a:%d,%d,%d\n", 0[p], 1[p], 2[p]);
}
saigon(p, n - 1, a, t);
}
}
int main(void)
{
int p[3] = {0};
int converted;
puts("Disks?");
converted = scanf("%d", &p[0]);
if (converted == 1) {
printf("b:%d,%d,%d\n", p[0], p[1], p[2]);
saigon(p, p[0], 0, 2);
} else
puts("failed to convert integer with scanf()");
return 0;
}
This is the same thing in assembly langauge (generated by the compiler):
; -- Machine type IA32
; mark_description "Intel(R) C++ Compiler for 32-bit applications, Version 6.0
Build 020611Z";
; mark_description "-Qvc6 -Qlocation,link,C:\\lang\\VC98\\Bin -W4 -Ox -FAs";
;ident "Intel(R) C++ Compiler for 32-bit applications, Version 6.0 Build
020611Z"
;ident "-Qvc6 -Qlocation,link,C:\lang\VC98\Bin -W4 -Ox -FAs"
.486P
.387
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
ALIGN 004H
_DATA ENDS
_BSS SEGMENT DWORD PUBLIC USE32 'BSS'
ALIGN 004H
_BSS ENDS
_RDATA SEGMENT DWORD PUBLIC USE32 'DATA'
ALIGN 004H
_RDATA ENDS
_TLS SEGMENT DWORD PUBLIC USE32 'TLS'
ALIGN 004H
_TLS ENDS
_DATA1 SEGMENT DWORD PUBLIC USE32 'DATA'
ALIGN 004H
_DATA1 ENDS
_TEXT1 SEGMENT DWORD PUBLIC USE32 'CODE'
ALIGN 004H
_TEXT1 ENDS
ASSUME CS:FLAT,DS:FLAT,SS:FLAT
;ident "-?comment:Intel(R) C++ Compiler for 32-bit applications, Version 6.0
Build 020611Z : hanoi.c : -Qvc6 -Qlocation,link,C:\\lang\\VC98\\Bin -W4 -Ox
-FAs"
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
_DATA ENDS
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
; -- Begin _saigon
; mark_begin;
IF @Version GE 612
.MMX
MMWORD TEXTEQU <QWORD>
ENDIF
IF @Version GE 614
.XMM
XMMWORD TEXTEQU <OWORD>
ENDIF
ALIGN 4
; parameter 1: 24 + esp
; parameter 2: 28 + esp
; parameter 3: 32 + esp
; parameter 4: 36 + esp
PUBLIC _saigon
_saigon PROC NEAR
.B1.1: ; Preds .B1.0
;;; {
push ebx ;3.1
sub esp, 16 ;3.1
mov ecx, DWORD PTR [esp+24] ;2.17
mov edx, DWORD PTR [esp+28] ;2.17
mov eax, DWORD PTR [esp+32] ;2.17
mov ebx, DWORD PTR [esp+36] ;2.17
mov DWORD PTR [esp+4], esi ;2.17
mov esi, edx ;2.17
mov DWORD PTR [esp+8], edi ;2.17
mov DWORD PTR [esp+12], ebp ;2.17
mov ebp, eax ;2.17
; LOE ecx ebx ebp esi
.B1.2: ; Preds .B1.11 .B1.1
;;; int a;
;;; if (n == 1) {
cmp esi, 1 ;5.5
je .B1.13 ; Prob 5% ;5.5
; LOE ebx ebp esi
.B1.3: ; Preds .B1.2
;;; s[p]--;
;;; t[p]++;
;;; printf("a:%d,%d,%d\n", 0[p], 1[p], 2[p]);
;;; } else {
;;; a = (t && s) ? 0 :
test ebx, ebx ;10.14
je .B1.6 ; Prob 50% ;10.14
; LOE ebx ebp esi
.B1.4: ; Preds .B1.3
test ebp, ebp ;10.14
je .B1.6 ; Prob 50% ;10.14
; LOE ebx ebp esi
.B1.5: ; Preds .B1.4
xor edi, edi ;10.9
jmp .B1.9 ; Prob 100% ;10.9
ALIGN 4
; LOE ebx ebp esi edi
.B1.6: ; Preds .B1.4 .B1.3
;;; (t != 1 && s != 1) ? 1 : 2;
cmp ebx, 1 ;11.14
je .B1.12 ; Prob 16% ;11.14
; LOE ebx ebp esi
.B1.7: ; Preds .B1.6
cmp ebp, 1 ;11.14
je .B1.12 ; Prob 16% ;11.14
; LOE ebx ebp esi
.B1.8: ; Preds .B1.7
mov edi, 1 ;10.9
; LOE ebx ebp esi edi
.B1.9: ; Preds .B1.5 .B1.8 .B1.12
;;; saigon(p, n - 1, s, a);
dec esi ;12.19
push edi ;12.29
push ebp ;12.29
push esi ;12.29
mov ecx, DWORD PTR [esp+36] ;12.29
push ecx ;12.29
call _saigon ;12.29
; LOE ebx ebp esi edi
.B1.10: ; Preds .B1.9
;;; {
;;; s[p]--;
mov ecx, DWORD PTR [esp+40] ;14.15
dec DWORD PTR [ecx+ebp*4] ;14.15
;;; t[p]++;
inc DWORD PTR [ecx+ebx*4] ;15.15
;;; printf("a:%d,%d,%d\n", 0[p], 1[p], 2[p]);
push DWORD PTR [ecx+8] ;16.50
push DWORD PTR [ecx+4] ;16.50
push DWORD PTR [ecx] ;16.50
push OFFSET FLAT: __STRING.1 ;16.50
call _printf ;16.50
; LOE ebx esi edi
.B1.17: ; Preds .B1.10
add esp, 32 ;16.50
; LOE ebx esi edi
.B1.11: ; Preds .B1.17
mov ebp, edi ;10.9
jmp .B1.2 ; Prob 100% ;10.9
ALIGN 4
; LOE ebx ebp esi
.B1.12: ; Preds .B1.7 .B1.6
mov edi, 2 ;10.9
jmp .B1.9 ; Prob 100% ;10.9
ALIGN 4
; LOE ebx ebp esi edi
.B1.13: ; Preds .B1.2 ; Infreq
mov eax, ebp ;
mov ecx, DWORD PTR [esp+24] ;
mov esi, DWORD PTR [esp+4] ;
mov edi, DWORD PTR [esp+8] ;
mov ebp, DWORD PTR [esp+12] ;
dec DWORD PTR [ecx+eax*4] ;6.11
inc DWORD PTR [ecx+ebx*4] ;7.11
push DWORD PTR [ecx+8] ;8.46
push DWORD PTR [ecx+4] ;8.46
push DWORD PTR [ecx] ;8.46
push OFFSET FLAT: __STRING.0 ;8.46
call _printf ;8.46
; LOE ebp esi edi
.B1.14: ; Preds .B1.13 ; Infreq
;;; }
;;; saigon(p, n - 1, a, t);
;;; }
;;; }
add esp, 32 ;20.1
pop ebx ;20.1
ret ;20.1
ALIGN 4
; LOE
; mark_end;
_saigon ENDP
_TEXT ENDS
_DATA1 SEGMENT DWORD PUBLIC USE32 'DATA'
__STRING.0 DB 97 ; s8
DB 58 ; s8
DB 37 ; s8
DB 100 ; s8
DB 44 ; s8
DB 37 ; s8
DB 100 ; s8
DB 44 ; s8
DB 37 ; s8
DB 100 ; s8
DB 10 ; s8
DB 0 ; s8
__STRING.1 DB 97 ; s8
DB 58 ; s8
DB 37 ; s8
DB 100 ; s8
DB 44 ; s8
DB 37 ; s8
DB 100 ; s8
DB 44 ; s8
DB 37 ; s8
DB 100 ; s8
DB 10 ; s8
DB 0 ; s8
_DATA1 ENDS
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
_DATA ENDS
; -- End _saigon
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
_DATA ENDS
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
; -- Begin _main
; mark_begin;
ALIGN 4
PUBLIC _main
_main PROC NEAR
.B2.1: ; Preds .B2.0
;;; {
push ebp ;22.1
mov ebp, esp ;22.1
sub esp, 3 ;22.1
and esp, -8 ;22.1
add esp, 4 ;22.1
sub esp, 16 ;22.1
;;; int p[3] = {0};
xor eax, eax ;23.21
mov DWORD PTR [esp], eax ;23.21
mov DWORD PTR [esp+4], eax ;23.21
mov DWORD PTR [esp+8], eax ;23.21
;;; int converted;
;;; puts("Disks?");
push OFFSET FLAT: __STRING.2 ;25.5
call _puts ;25.5
; LOE ebx esi edi
.B2.2: ; Preds .B2.1
;;; converted = scanf("%d", &p[0]);
lea eax, DWORD PTR [esp+4] ;26.30
push eax ;26.30
push OFFSET FLAT: __STRING.3 ;26.30
call _scanf ;26.30
; LOE eax ebx esi edi
.B2.10: ; Preds .B2.2
add esp, 12 ;26.30
; LOE eax ebx esi edi
.B2.3: ; Preds .B2.10
;;; if (converted == 1) {
cmp eax, 1 ;27.5
je .B2.6 ; Prob 16% ;27.5
; LOE ebx esi edi
.B2.4: ; Preds .B2.3
;;; printf("b:%d,%d,%d\n", p[0], p[1], p[2]);
;;; saigon(p, p[0], 0, 2);
;;; } else
;;; puts("failed to convert integer with scanf()");
push OFFSET FLAT: __STRING.5 ;31.9
call _puts ;31.9
; LOE ebx esi edi
.B2.11: ; Preds .B2.4
pop ecx ;31.9
; LOE ebx esi edi
.B2.5: ; Preds .B2.12 .B2.11
;;; return 0;
xor eax, eax ;32.5
add esp, 16 ;32.5
mov esp, ebp ;32.5
pop ebp ;32.5
ret ;32.5
; LOE
.B2.6: ; Preds .B2.3 ; Infreq
push DWORD PTR [esp+8] ;28.44
push DWORD PTR [esp+8] ;28.44
push DWORD PTR [esp+8] ;28.44
push OFFSET FLAT: __STRING.4 ;28.44
call _printf ;28.44
; LOE ebx esi edi
.B2.7: ; Preds .B2.6 ; Infreq
lea eax, DWORD PTR [esp+16] ;29.16
push 2 ;29.19
push 0 ;29.19
push DWORD PTR [esp+24] ;29.19
push eax ;29.19
call _saigon ;29.19
; LOE ebx esi edi
.B2.12: ; Preds .B2.7 ; Infreq
add esp, 32 ;29.19
jmp .B2.5 ; Prob 100% ;29.19
ALIGN 4
; LOE ebx esi edi
; mark_end;
_main ENDP
_TEXT ENDS
_DATA1 SEGMENT DWORD PUBLIC USE32 'DATA'
p_113.0 DD 0 ; s32
DD 0 ; s32
DD 0 ; s32
__STRING.4 DB 98 ; s8
DB 58 ; s8
DB 37 ; s8
DB 100 ; s8
DB 44 ; s8
DB 37 ; s8
DB 100 ; s8
DB 44 ; s8
DB 37 ; s8
DB 100 ; s8
DB 10 ; s8
DB 0 ; s8
__STRING.5 DB 102 ; s8
DB 97 ; s8
DB 105 ; s8
DB 108 ; s8
DB 101 ; s8
DB 100 ; s8
DB 32 ; s8
DB 116 ; s8
DB 111 ; s8
DB 32 ; s8
DB 99 ; s8
DB 111 ; s8
DB 110 ; s8
DB 118 ; s8
DB 101 ; s8
DB 114 ; s8
DB 116 ; s8
DB 32 ; s8
DB 105 ; s8
DB 110 ; s8
DB 116 ; s8
DB 101 ; s8
DB 103 ; s8
DB 101 ; s8
DB 114 ; s8
DB 32 ; s8
DB 119 ; s8
DB 105 ; s8
DB 116 ; s8
DB 104 ; s8
DB 32 ; s8
DB 115 ; s8
DB 99 ; s8
DB 97 ; s8
DB 110 ; s8
DB 102 ; s8
DB 40 ; s8
DB 41 ; s8
DB 0 ; s8
DB 1 DUP (0) ; pad
__STRING.3 DB 37 ; s8
DB 100 ; s8
DB 0 ; s8
DB 1 DUP (0) ; pad
__STRING.2 DB 68 ; s8
DB 105 ; s8
DB 115 ; s8
DB 107 ; s8
DB 115 ; s8
DB 63 ; s8
DB 0 ; s8
_DATA1 ENDS
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
_DATA ENDS
; -- End _main
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
_DATA ENDS
EXTRN _scanf:PROC
EXTRN _puts:PROC
EXTRN _printf:PROC
END
If you are not planning to call from a HLL, it can be a bit simpler but as you
can see, it takes a lot more lines of code to do the same thing in assembly
lanaguage as it does in C.
I happen to think that assembly language is a very good first language. I
highly recommend Knuth's MIX language (and even have a MIX compiler to play
with).
However, I would not write a chess program in assembly langauge. Far too
tedious. However, it is good to know some to give the slow spots a bit of
grease when needed.
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.