Just playing about really, but I thought it would be worth re-affirming in my brain that you have to be careful using assembler instructions like CLW, CLQ etc. when dealing with unsigned numbers since they propagate the sign bit.:
gives
#include <stdio.h>
void extend(unsigned char x)
{
int y;
asm ("xor %%eax, %%eax;\n\t" /* clear EAX */
"movb %1, %%al;\n\t" /* move the byte x into AL */
"cbw;\n\t"
"movl %%eax, %0;\n\t"
:"=r"(y) /* output only */
:"r"(x) /* input */
:"%eax"); /* clobbered regs */
printf("x=%d, cbw extended=%d\n", x, y);
}
int main(void)
{
extend(127);
extend(128);
return 0;
}
there is no binary flag for printf in C, but in Common Lisp:
~/c/tmp> ./a.out
x=127, cbw extended=127
x=128, cbw extended=65408
Instead of doing it in inline C, I thought I’d try nasm + gcc
CL-USER> (format t "~20B~%" 128)
10000000
NIL
CL-USER> (format t "~20B~%" 65408)
1111111110000000
NIL
building and running with
extern printf
SECTION .data
fmt: db "cbw %d (previously %d)", 10, 0
SECTION .text
global main ; needed for gcc
main:
push ebp
mov ebp,esp
xor eax,eax
mov ax, 128
push eax
cbw
push eax
push dword fmt
call printf
add esp, 12 ; pop 3 pushes
mov esp, ebp ; clean stack frame
pop ebp
mov eax,0 ; no error return
ret
~/c/tmp> nasm -f elf nasm2.asm
~/c/tmp> gcc -o nasm2 nasm2.o
~/c/tmp> nasm2
cbw 65408 (previously 128)


