endian_demo.c // C 主程式,實現 main()
function.S // AT&T 語法組合語言,實現 swapEnds、writeHexASCII
Makefile // 編譯腳本
%esp 取值。%eax 傳回。%ebp 為幀指標,區域變數用負偏移,參數用正偏移(4(%esp) 為第一參數,8(%esp) 為第二參數...)。.text
.code32
.globl writeHexASCII
.globl swapEnds
將整數轉為 8 位十六進位 ASCII 字串存入緩衝區。
writeHexASCII:
movl $28, %ecx # 位移量初始值 (7*4)
movl $0, %edi # 迴圈計數器
mov 0x4(%esp), %edx # buffer 位址
jmp if_loop_end
loop_start:
mov 0x8(%esp), %eax # number
shr %cl, %eax # 右移取 4 bits
and $0xf, %eax # 取低 4 位
cmpl $9, %eax
jg hex_abcdef
hex_0_9:
addl $0x30, %eax # '0'-'9'
jmp hex_convert_complete
hex_abcdef:
addl $0x57, %eax # 'A'-'F'
hex_convert_complete:
mov %al, (%edx) # 存入 buffer
add $1, %edx
subl $4, %ecx # 下一組 4 bits
addl $1, %edi
if_loop_end:
cmpl $7, %edi
jle loop_start
movb $0x0, (%edx) # 結尾 \0
ret
swapEnds:
mov 4(%esp), %eax
and $0xff000000, %eax
shr $24, %eax
mov %eax, %edi # 保存最高位元組到 edi
movzbl 4(%esp), %eax # 取最低位元組 (零擴展)
shl $24, %eax
or %eax, %edi # 合併到 edi
mov 4(%esp), %eax
and $0xff0000, %eax
shr $8, %eax
or %eax, %edi
mov 4(%esp), %eax
and $0xff00, %eax
shl $8, %eax
or %eax, %edi
mov %edi, %eax # 結果放入 eax 返回
ret
extern void writeHexASCII(char *buffer, unsigned int number);
extern unsigned int swapEnds(unsigned int x);
all: endian_demo
endian_demo: function.o endian_demo.o
gcc -o $@ function.o endian_demo.o
function.o: function.S
gcc -o $@ -c $<
endian_demo.o: endian_demo.c
gcc -o $@ -c $< -ansi
clean:
rm -f *.o endian_demo
$ make
$ ./endian_demo 1 255 1334
1: 00000001 <-> 01000000 = 16777216
255: 000000FF <-> FF000000 = 4278190080
1334: 00000536 <-> 36050000 = 905969664
來源:「techlife」博客,原文連結:https://techlife.blog.51cto.com/212583/55348。