我正在研究一个C程序,该程序调用将数组作为参数传递的汇编函数。
在汇编代码中(用于8086),无法获取内存中数组的地址,因此将地址保存在BARCODE
中,但是之后我需要将值复制到tha数组unsigned char computeControlDigit(char* barCodeASCII);
int main( void ){
char barCodeStr[14]
unsigned char controlDigitCheck;
controlDigitCheck = computeControlDigit(barCodeStr);
}
中,但是我无法找到任何方法来实现这一目标。
我的代码如下:
Ccode:
_DATA SEGMENT WORD PUBLIC 'DATA'
BARCODE DB 13 DUP(?)
_DATA ENDS
PUBLIC _computeControlDigit
_computeControlDigit PROC FAR
PUSH BP
MOV BP, SP
PUSH ES
LES BX, [BP+6]
; code to copy from memory to
; array and code of operations on the array
POP ES
POP BP
RET
_computeControlDigit ENDP
_TEXT ENDS
END
Assemby代码:
@Injectable()
export class AppGuard implements CanActivate {
constructor(private store: Store<fromAppStore.AppState>) {}
canActivate(): Observable<boolean> {
return this.checkAppStore().pipe(
switchMap(() => of(true)),
catchError(() => of(false))
);
}
checkAppStore(): Observable<boolean> {
return this.store.pipe(select(fromAppStore.areAppsLoaded)).pipe(
tap(loaded => {
if (!loaded) {
this.store.dispatch(new fromAppStore.LoadApps());
}
}),
filter(loaded => loaded),
take(1)
);
}
}
欢迎任何帮助。
答案 0 :(得分:1)
您可以使用
mov al,es:[bx]
可以从字符串中读取字符,但是由于这是大型模型,因此您需要创建一个指向BARCODE的远端指针。您可能要考虑将ds:si用作输入,将es:di用作输出,因为这将使代码成为lodsb和stosb。
答案 1 :(得分:1)
在大内存模型中,所有数据和代码均为FAR,必须通过适当的段进行引用。在下面的代码中,我将指向源字符串barcodestr
的指针加载到 DS:SI 中,将BARCODE
的指针加载到 ES:DI 中。然后,我使用LODSB从barcodestr
数组中读取字符,并使用STOSB
将其保存到BARCODE
中。到达NUL终止符后,复制完成。
STOSB
与 1 类似:
mov [ES:DI], al
inc di
LODSB
与 1 类似:
mov al, [DS:SI]
inc si
我不知道您是使用MASM还是TASM作为汇编程序,因此我同时提供了两者的版本。仅复制NUL终止字符串的TASM代码示例如下:
.MODEL LARGE, C
PUBLIC computeControlDigit
_DATA SEGMENT WORD PUBLIC 'DATA'
BARCODE DB 13 DUP(?)
_DATA ENDS
_TEXT SEGMENT WORD PUBLIC 'TEXT'
ASSUME DS:_DATA, CS:_TEXT
computeControlDigit PROC C FAR
ARG %%barcodestr:DWORD ; barcodestr is a FAR pointer (DWORD)
USES DS, SI, DI ; Save non-volatile registers
MOV AX, SEG BARCODE ; Get segment and offset (FAR PTR) of BARCODE
MOV ES, AX ; into ES:DI
MOV DI, OFFSET BARCODE
LDS SI, %%barcodestr ; Load barcodestr FAR pointer into DS:SI
JMP %%GETCHAR ; Get next character
%%NEXTCHAR:
STOSB ; Store character to ES:DI (BARCODE), DI++
%%GETCHAR:
LODSB ; Read character from DS:SI (barcodestr), SI++
TEST AL, AL ; Is it a NUL terminator?
JNZ %%NEXTCHAR ; If not go back and get next character
%%ENDLOOP:
STOSB ; Store NUL terminator at end of BARCODE
RET
computeControlDigit ENDP
_TEXT ENDS
END
当然,您可以进行选择的任何处理。我只是直接复制了数据作为示例。
如果使用MASM,则可能必须使用略有不同的语法:
.MODEL LARGE, C
PUBLIC computeControlDigit
_DATA SEGMENT WORD PUBLIC 'DATA'
BARCODE DB 13 DUP(?)
_DATA ENDS
_TEXT SEGMENT WORD PUBLIC 'TEXT'
ASSUME DS:_DATA, CS:_TEXT
computeControlDigit PROC FAR C USES DS SI DI barcodestr:DWORD
; DS, SI, DI are saved as they are non-volatile registers
; barcodestr is a FAR pointer (DWORD)
MOV AX, SEG BARCODE ; Get segment and offset (FAR PTR) of BARCODE
MOV ES, AX ; into ES:DI
MOV DI, OFFSET BARCODE
LDS SI, barcodestr ; Load barcodestr FAR pointer into DS:SI
JMP GETCHAR ; Get next character
NEXTCHAR:
STOSB ; Store character to ES:DI (BARCODE), DI++
GETCHAR:
LODSB ; Read character from DS:SI (barcodestr), SI++
TEST AL, AL ; Is it a NUL terminator?
JNZ NEXTCHAR ; If not go back and get next character
STOSB ; Store NUL terminator at end of BARCODE
RET
computeControlDigit ENDP
_TEXT ENDS
END
不使用您可能更自然的特殊汇编指令的原始版本将是:
PUBLIC _computeControlDigit
_DATA SEGMENT WORD PUBLIC USE16 'DATA'
BARCODE:
DB 13 DUP(?)
_DATA ENDS
_TEXT SEGMENT WORD PUBLIC USE16 'TEXT'
ASSUME CS:_TEXT, DS:_DATA
_computeControlDigit:
push bp
mov bp,sp
push ds
push si
push di
mov ax,seg BARCODE
mov es,ax
mov di,offset BARCODE
lds si,dword ptr 6[bp]
jmp GETCHAR
NEXTCHAR:
stosb
GETCHAR:
lodsb
test al,al
jne NEXTCHAR
stosb
pop di
pop si
pop ds
pop bp
retf
_TEXT ENDS
END
LODSB
和STOSB
与所示的等效代码相似,除了LODSB
和{{1} }请勿更改标志。