重慶分公司,新征程啟航
為企業(yè)提供網(wǎng)站建設、域名注冊、服務器等服務
為企業(yè)提供網(wǎng)站建設、域名注冊、服務器等服務
試編寫ARM匯編程序和C語言程序,實現(xiàn)下面的功能:
在匯編程序中實現(xiàn)內(nèi)存塊移動xx_memmove的子程序;
參數(shù)1:源地址:
參數(shù)2:目的地址;
參數(shù)3:移動字節(jié)數(shù);
compare的功能是比較兩個地址參數(shù)的大小,并被匯編程序glj_memmove調(diào)用;
代碼+注釋:
int compare(int src, int dest)
{//進來后篡改了R2的值,size(r2)要備份
if(src< dest)//
return 0;//src_dest,src在dest左邊,src從后往前拷貝
return 1;//dest_src,否則src在dest右邊,src從前往后拷貝
}
(二) 使用給定的memmove_test調(diào)用匯編實現(xiàn)的內(nèi)存塊移動函數(shù)代碼+注釋:
IMPORT cFun
IMPORT compare ;導入compare()
AREA asmfile, CODE, READONLY
EXPORT glj_memmove ;導出glj_memmove()
ENTRY
glj_memmove
;src=M[R[R0]]=M[0x10000FC4]="1234567890ABABABABABABABABABABABABABABABAB"
;dest=M[R[R1]]=M[0x10000FD8]="ABABABABABABABABABABAB"
;size=R[R2]=12
STMFD sp!,{r0-r12,lr};保存進入函數(shù)前的現(xiàn)場資源,保存的函數(shù)返回地址
mov r4,r0 ;備份src
mov r5,r1 ;備份dest
mov r6,r2 ;備份size
bl compare
cmp r0,#0
mov r0,r4 ;恢復src
mov r1,r5 ;恢復dest
mov r2,r6 ;恢復size
beq src_dest ;srcdest 無所謂重疊 src從前往后拷貝
src_dest
;先判斷src,dest是否4字節(jié)對齊
;再判斷size是否為4字節(jié)對齊
mvn r8,#3 ;r8=~0b0011=0b1100
bics r7,r0,r8 ;r7=src&(~0b1100) 保留后兩位,與上0x03不是同樣的效果?
bics r7,r1,r8 ;r7=dest&(~0b1100) 保留后兩位
movne r8,#0 ;此時r8作為標志位,ne滿足則r8清零
bne src_dest_1 ;低兩位不為0,說明不是4字節(jié)對齊
bics r7,r2,r8 ;r7=size&(~0b1100) 保留后兩位即為需要1字節(jié)拷貝的size
beq src_dest_4 ;若r7=0即沒有,則只用四字節(jié)拷貝即可
bne src_dest_1 ;r7不為0,需要1字節(jié)拷貝
src_dest_4
sub r2,r2,#4 ;r2=r2-4,為后面計算ldr末起始地址服務
add r0,r0,r2 ;r0=src+size-4
add r1,r1,r2 ;r1=dest+size-4
add r2,r2,#4 ;恢復r2 size
src_dest_loop_4 ;注:size非4對齊,末地址也不對齊,可以先一字節(jié)搬運,當
ldr r4,[r0],#-4 ;用r4來搬運內(nèi)存數(shù)據(jù)(按字),搬完地址-4
str r4,[r1],#-4 ;最后的時候r0,r1多減了4
subs r2,r2,#4 ;統(tǒng)計剩余字節(jié)數(shù)
bgt src_dest_loop_4 ;還有size,繼續(xù)重復搬運
b out ;否則,搬完結(jié)束,退出子程序
src_dest_1 ;可以分支也可以不分,不分就重寫一個;方便起見干脆重寫一個src_dest_1_all
sub r2,r2,#1 ;r2=r2-1,為后面計算末地址服務
add r0,r0,r2 ;r0=src+size-1 0+10-1=9
add r1,r1,r2 ;r1=dest+size-1
add r2,r2,#1 ;恢復r2 size
cmp r8,#0
beq src_dest_loop_1_all ;r7!=0
mov r8,r7 ;備份r7
src_dest_loop_1_4
ldrb r4,[r0],#-1;
strb r4,[r1],#-1;結(jié)束后r0,r1修正+1 ->ldr -4
;mov r8,r7 ;這玩意不能放循環(huán)里,這里r8沒用了可以被覆蓋,但r7原值后面還有用,先備份
subs r7,r7,#1 ;r7遞減計數(shù); 10-8=2; 2-1-1=0; src ->9-1-1=7 r0,r1修正+1 ->ldr -4這里r8沒用了,可以被覆蓋
;sub r2,r2,#1 ;同步更新剩余的字節(jié)數(shù),多此一舉了(這里沒法設標志位,否則后面害得cmp)
bne src_dest_loop_1_4
add r0,r0,#1 ;src地址修正為實際末地址+1
add r1,r1,#1 ;dest同上
sub r0,r0,#4 ;
sub r1,r1,#4
subs r2,r2,r8 ;更新剩余的字節(jié)數(shù)
beq out
b src_dest_loop_4 ;修正好,直接進入循環(huán)就可
src_dest_loop_1_all
ldrb r4,[r0],#-1
strb r4,[r1],#-1
sub r2,r2,#1
bne src_dest_loop_1_all
b out
dest_src
mvn r8,#3 ;r8=~0b0011=0b1100
bic r7,r0,r8 ;r7=src&(~0b1100) 保留后兩位
bic r8,r1,r8 ;r7=dest&(~0b1100) 保留后兩位
orrs r7,r7,r8
bgt dest_src_loop_1;正序不對齊先4后1
dest_src_loop_4
ldr r4,[r0],#4
str r4,[r1],#4
sub r2,r2,#4 ;統(tǒng)計剩余字節(jié)數(shù)
cmp r2,#4 ;看看剩余字節(jié)數(shù)是否有4個,若有則正常運行,若無則跳轉(zhuǎn)1字節(jié)move
bpl dest_src_loop_4 ;還有size,繼續(xù)重復搬運
subs r2,r2,#0 ;r2<4,再看r2是否為0,同時更新剩余size
beq out
sub r0,r0,#4 ;地址修正
sub r1,r1,#4
dest_src_loop_1 ;r2不為0,繼續(xù)1字節(jié)move
ldrb r4,[r0],#1 ;!!!
strb r4,[r1],#1 ;!!!
subs r2,r2,#1
bgt dest_src_loop_1
b out
out
LDMFD sp!,{r0-r12,pc};恢復進入函數(shù)前的現(xiàn)場資源,把先前保存的函數(shù)返回地址傳給pc
end
(三) 調(diào)試查看結(jié)果(debug-watch)
可通過所有測試。
個人制作,僅供參考
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧